ImsPhoneCallTracker.java revision 52c1bebcaf545d679923ffbac870eb581faf2b13
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;
31a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Handler;
32a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Message;
33a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Registrant;
34a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.RegistrantList;
35ea8cb63201520592011a92849ad3661d22776c87Andrew Leeimport android.os.RemoteException;
36a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.SystemProperties;
37b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganeshimport android.provider.Settings;
38a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.preference.PreferenceManager;
39fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunnimport android.telecom.ConferenceParticipant;
40dc2b5d1c32cad5269106d00fd106bd64097238f4Tyler Gunnimport android.telecom.VideoProfile;
41a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.DisconnectCause;
42a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.PhoneNumberUtils;
43a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.Rlog;
4404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport android.telephony.ServiceState;
45a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsCall;
4704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsCallProfile;
48cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.comimport com.android.ims.ImsConfig;
4904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsConnectionStateListener;
5004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsEcbm;
5104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsException;
5204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsManager;
5304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsReasonInfo;
5404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsServiceClass;
5504e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsUtInterface;
56ea8cb63201520592011a92849ad3661d22776c87Andrew Leeimport com.android.ims.internal.IImsVideoCallProvider;
57ea8cb63201520592011a92849ad3661d22776c87Andrew Leeimport com.android.ims.internal.ImsVideoCallProviderWrapper;
58a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.Call;
59a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.CallStateException;
60a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.CallTracker;
61a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.CommandException;
62a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.CommandsInterface;
63a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.Connection;
64a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.Phone;
65a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.PhoneBase;
66a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.PhoneConstants;
67a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.TelephonyProperties;
68a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
69a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville/**
70a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * {@hide}
71a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville */
72a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savillepublic final class ImsPhoneCallTracker extends CallTracker {
73a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    static final String LOG_TAG = "ImsPhoneCallTracker";
74a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
75a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private static final boolean DBG = true;
76a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
7762a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com    private boolean[] mImsFeatureEnabled = {false, false, false, false};
78cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com
79a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
80a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
81a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onReceive(Context context, Intent intent) {
82a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (intent.getAction().equals(ImsManager.ACTION_IMS_INCOMING_CALL)) {
83a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (DBG) log("onReceive : incoming call intent");
84a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
85a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mImsManager == null) return;
86a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
87a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mServiceId < 0) return;
88a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
89a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                try {
90a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    // Network initiated USSD will be treated by mImsUssdListener
91a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    boolean isUssd = intent.getBooleanExtra(ImsManager.EXTRA_USSD, false);
92a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    if (isUssd) {
93a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        if (DBG) log("onReceive : USSD");
94a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        mUssdSession = mImsManager.takeCall(mServiceId, intent, mImsUssdListener);
95a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        if (mUssdSession != null) {
962999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn                            mUssdSession.accept(ImsCallProfile.CALL_TYPE_VOICE);
97a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        }
98a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        return;
99a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    }
100a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
101a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    // Normal MT call
102a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    ImsCall imsCall = mImsManager.takeCall(mServiceId, intent, mImsCallListener);
103a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    ImsPhoneConnection conn = new ImsPhoneConnection(mPhone.getContext(), imsCall,
104a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            ImsPhoneCallTracker.this, mRingingCall);
105a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    addConnection(conn);
106a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
107288268d5528e0df03f348e303954813cb188c55bRekha Kumar                    setVideoCallProvider(conn, imsCall);
108ea8cb63201520592011a92849ad3661d22776c87Andrew Lee
109a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    if ((mForegroundCall.getState() != ImsPhoneCall.State.IDLE) ||
110a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            (mBackgroundCall.getState() != ImsPhoneCall.State.IDLE)) {
111a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        conn.update(imsCall, ImsPhoneCall.State.WAITING);
112a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    }
113a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
114a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPhone.notifyNewRingingConnection(conn);
115a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPhone.notifyIncomingRing();
116a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
117a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    updatePhoneState();
118a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPhone.notifyPreciseCallStateChanged();
119a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                } catch (ImsException e) {
120a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    loge("onReceive : exception " + e);
121ea8cb63201520592011a92849ad3661d22776c87Andrew Lee                } catch (RemoteException e) {
122a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
123a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
124a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
125a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    };
126a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
127a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Constants
128a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
129a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    static final int MAX_CONNECTIONS = 7;
130a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    static final int MAX_CONNECTIONS_PER_CALL = 5;
131a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
132a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private static final int EVENT_HANGUP_PENDINGMO = 18;
133a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private static final int EVENT_RESUME_BACKGROUND = 19;
134a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private static final int EVENT_DIAL_PENDINGMO = 20;
135a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
136a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private static final int TIMEOUT_HANGUP_PENDINGMO = 500;
137a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
138a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Instance Variables
139a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ArrayList<ImsPhoneConnection> mConnections = new ArrayList<ImsPhoneConnection>();
140a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private RegistrantList mVoiceCallEndedRegistrants = new RegistrantList();
141a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private RegistrantList mVoiceCallStartedRegistrants = new RegistrantList();
142a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
143a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    ImsPhoneCall mRingingCall = new ImsPhoneCall(this);
144a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    ImsPhoneCall mForegroundCall = new ImsPhoneCall(this);
145a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    ImsPhoneCall mBackgroundCall = new ImsPhoneCall(this);
146a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    ImsPhoneCall mHandoverCall = new ImsPhoneCall(this);
147a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
148a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ImsPhoneConnection mPendingMO;
149a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private int mClirMode = CommandsInterface.CLIR_DEFAULT;
150a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private Object mSyncHold = new Object();
151a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
152a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ImsCall mUssdSession = null;
153a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private Message mPendingUssd = null;
154a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
155a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    ImsPhone mPhone;
156a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
157a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private boolean mDesiredMute = false;    // false = mute off
158a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private boolean mOnHoldToneStarted = false;
159a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
160a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    PhoneConstants.State mState = PhoneConstants.State.IDLE;
161a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
162a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ImsManager mImsManager;
163a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private int mServiceId = -1;
164a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
165a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private Call.SrvccState mSrvccState = Call.SrvccState.NONE;
166a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
16704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    private boolean mIsInEmergencyCall = false;
16804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
16904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    private int pendingCallClirMode;
170288268d5528e0df03f348e303954813cb188c55bRekha Kumar    private int mPendingCallVideoState;
17104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    private boolean pendingCallInEcm = false;
172276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn    private boolean mSwitchingFgAndBgCalls = false;
173276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn    private ImsCall mCallExpectedToResume = null;
17404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
175a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Events
176a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
177a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
178a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Constructors
179a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
180a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    ImsPhoneCallTracker(ImsPhone phone) {
181a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        this.mPhone = phone;
182a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
183a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        IntentFilter intentfilter = new IntentFilter();
184a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        intentfilter.addAction(ImsManager.ACTION_IMS_INCOMING_CALL);
185a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getContext().registerReceiver(mReceiver, intentfilter);
186a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
187a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Thread t = new Thread() {
188a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            public void run() {
189a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                getImsService();
190a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
191a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        };
192a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        t.start();
193a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
194a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
195a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private PendingIntent createIncomingCallPendingIntent() {
196a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Intent intent = new Intent(ImsManager.ACTION_IMS_INCOMING_CALL);
197a89314bcc94c43512299131609feea0c2c8167cfLibin.Tang@motorola.com        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
198a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
199a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                PendingIntent.FLAG_UPDATE_CURRENT);
200a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
201a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
202a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void getImsService() {
203a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("getImsService");
20453dde7e076954c250e55d156cc1df1202c3a8a9eEtan Cohen        mImsManager = ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId());
205a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
206a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mServiceId = mImsManager.open(ImsServiceClass.MMTEL,
207a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    createIncomingCallPendingIntent(),
208a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mImsConnectionStateListener);
20904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
21004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            // Get the ECBM interface and set IMSPhone's listener object for notifications
21104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            getEcbmInterface().setEcbmStateListener(mPhone.mImsEcbmStateListener);
21204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            if (mPhone.isInEcm()) {
21304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                // Call exit ECBM which will invoke onECBMExited
21404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                mPhone.exitEmergencyCallbackMode();
21504e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            }
216b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh            int mPreferredTtyMode = Settings.Secure.getInt(
217b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh                mPhone.getContext().getContentResolver(),
218b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh                Settings.Secure.PREFERRED_TTY_MODE,
219b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh                Phone.TTY_MODE_OFF);
220f1099a9dfe0250a6b343de0646413db4034381deEtan Cohen           mImsManager.setUiTTYMode(mPhone.getContext(), mServiceId, mPreferredTtyMode, null);
221b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh
222a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (ImsException e) {
223a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            loge("getImsService: " + e);
224a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            //Leave mImsManager as null, then CallStateException will be thrown when dialing
225a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mImsManager = null;
226a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
227a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
228a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
229a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void dispose() {
230a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("dispose");
231a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mRingingCall.dispose();
232a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mBackgroundCall.dispose();
233a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mForegroundCall.dispose();
234a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mHandoverCall.dispose();
235a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
236a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        clearDisconnected();
237a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getContext().unregisterReceiver(mReceiver);
238a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
239a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
240a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
241a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void finalize() {
242a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("ImsPhoneCallTracker finalized");
243a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
244a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
245a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Instance Methods
246a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
247a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Public Methods
248a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
249a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void registerForVoiceCallStarted(Handler h, int what, Object obj) {
250a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Registrant r = new Registrant(h, what, obj);
251a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mVoiceCallStartedRegistrants.add(r);
252a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
253a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
254a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
255a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void unregisterForVoiceCallStarted(Handler h) {
256a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mVoiceCallStartedRegistrants.remove(h);
257a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
258a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
259a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
260a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void registerForVoiceCallEnded(Handler h, int what, Object obj) {
261a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Registrant r = new Registrant(h, what, obj);
262a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mVoiceCallEndedRegistrants.add(r);
263a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
264a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
265a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
266a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void unregisterForVoiceCallEnded(Handler h) {
267a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mVoiceCallEndedRegistrants.remove(h);
268a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
269a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
270a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    Connection
2716bbcbfd62c9aa5787e7c33936e2246ff05b59d58Tyler Gunn    dial(String dialString, int videoState) throws CallStateException {
272a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
273a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        int oirMode = sp.getInt(PhoneBase.CLIR_KEY, CommandsInterface.CLIR_DEFAULT);
2746bbcbfd62c9aa5787e7c33936e2246ff05b59d58Tyler Gunn        return dial(dialString, oirMode, videoState);
275a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
276a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
277a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
278a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * oirMode is one of the CLIR_ constants
279a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
280a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    synchronized Connection
2816bbcbfd62c9aa5787e7c33936e2246ff05b59d58Tyler Gunn    dial(String dialString, int clirMode, int videoState) throws CallStateException {
28204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        boolean isPhoneInEcmMode = SystemProperties.getBoolean(
28304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                TelephonyProperties.PROPERTY_INECM_MODE, false);
28404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        boolean isEmergencyNumber = PhoneNumberUtils.isEmergencyNumber(dialString);
28504e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
286a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("dial clirMode=" + clirMode);
287a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
288a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // note that this triggers call state changed notif
289a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        clearDisconnected();
290a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
291a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mImsManager == null) {
292a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException("service not available");
293a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
294a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
295a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!canDial()) {
296a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException("cannot dial in current state");
297a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
298a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
29904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        if (isPhoneInEcmMode && isEmergencyNumber) {
30004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            handleEcmTimer(ImsPhone.CANCEL_ECM_TIMER);
30104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        }
30204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
303a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean holdBeforeDial = false;
304a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
305a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // The new call must be assigned to the foreground call.
306a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // That call must be idle, so place anything that's
307a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // there on hold
308a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mForegroundCall.getState() == ImsPhoneCall.State.ACTIVE) {
309a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (mBackgroundCall.getState() != ImsPhoneCall.State.IDLE) {
310a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //we should have failed in !canDial() above before we get here
311a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                throw new CallStateException("cannot dial in current state");
312a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
313a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            // foreground call is empty for the newly dialed connection
314a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            holdBeforeDial = true;
315288268d5528e0df03f348e303954813cb188c55bRekha Kumar            // Cache the video state for pending MO call.
316288268d5528e0df03f348e303954813cb188c55bRekha Kumar            mPendingCallVideoState = videoState;
317a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            switchWaitingOrHoldingAndActive();
318a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
319a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
320a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsPhoneCall.State fgState = ImsPhoneCall.State.IDLE;
321a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsPhoneCall.State bgState = ImsPhoneCall.State.IDLE;
322a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
323a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mClirMode = clirMode;
324a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
325a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        synchronized (mSyncHold) {
326a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (holdBeforeDial) {
327a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                fgState = mForegroundCall.getState();
328a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                bgState = mBackgroundCall.getState();
329a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
330a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //holding foreground call failed
331a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (fgState == ImsPhoneCall.State.ACTIVE) {
332a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    throw new CallStateException("cannot dial in current state");
333a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
334a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
335a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //holding foreground call succeeded
336a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (bgState == ImsPhoneCall.State.HOLDING) {
337a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    holdBeforeDial = false;
338a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
339a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
340a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
341a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPendingMO = new ImsPhoneConnection(mPhone.getContext(),
342a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    checkForTestEmergencyNumber(dialString), this, mForegroundCall);
343a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
344a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        addConnection(mPendingMO);
345a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
346a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!holdBeforeDial) {
34704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            if ((!isPhoneInEcmMode) || (isPhoneInEcmMode && isEmergencyNumber)) {
34804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                dialInternal(mPendingMO, clirMode, videoState);
34904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            } else {
35004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                try {
35104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                    getEcbmInterface().exitEmergencyCallbackMode();
35204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                } catch (ImsException e) {
35304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                    e.printStackTrace();
35404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                    throw new CallStateException("service not available");
35504e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                }
35604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                mPhone.setOnEcbModeExitResponse(this, EVENT_EXIT_ECM_RESPONSE_CDMA, null);
35704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                pendingCallClirMode = clirMode;
358288268d5528e0df03f348e303954813cb188c55bRekha Kumar                mPendingCallVideoState = videoState;
35904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                pendingCallInEcm = true;
36004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            }
361a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
362a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
363a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        updatePhoneState();
364a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.notifyPreciseCallStateChanged();
365a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
366a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mPendingMO;
367a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
368a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
36904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    private void handleEcmTimer(int action) {
37004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        mPhone.handleTimerInEmergencyCallbackMode(action);
37104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        switch (action) {
37204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            case ImsPhone.CANCEL_ECM_TIMER:
37304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                break;
37404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            case ImsPhone.RESTART_ECM_TIMER:
37504e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                break;
37604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            default:
37704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                log("handleEcmTimer, unsupported action " + action);
37804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        }
37904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    }
38004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
3816bbcbfd62c9aa5787e7c33936e2246ff05b59d58Tyler Gunn    private void dialInternal(ImsPhoneConnection conn, int clirMode, int videoState) {
382a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (conn == null) {
383a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return;
384a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
385a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
386a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (conn.getAddress()== null || conn.getAddress().length() == 0
387a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                || conn.getAddress().indexOf(PhoneNumberUtils.WILD) >= 0) {
388a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            // Phone number is invalid
389a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            conn.setDisconnectCause(DisconnectCause.INVALID_NUMBER);
390a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            sendEmptyMessageDelayed(EVENT_HANGUP_PENDINGMO, TIMEOUT_HANGUP_PENDINGMO);
391a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return;
392a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
393a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
394a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // Always unmute when initiating a new call
395a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        setMute(false);
396a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        int serviceType = PhoneNumberUtils.isEmergencyNumber(conn.getAddress()) ?
3976bbcbfd62c9aa5787e7c33936e2246ff05b59d58Tyler Gunn                ImsCallProfile.SERVICE_TYPE_EMERGENCY : ImsCallProfile.SERVICE_TYPE_NORMAL;
39864e62340aae85179a6468ccac4a401900eb4dc2fTyler Gunn        int callType = ImsCallProfile.getCallTypeFromVideoState(videoState);
39964e62340aae85179a6468ccac4a401900eb4dc2fTyler Gunn        //TODO(vt): Is this sufficient?  At what point do we know the video state of the call?
40064e62340aae85179a6468ccac4a401900eb4dc2fTyler Gunn        conn.setVideoState(videoState);
401a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
402a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
403a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            String[] callees = new String[] { conn.getAddress() };
404a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ImsCallProfile profile = mImsManager.createCallProfile(mServiceId,
4056bbcbfd62c9aa5787e7c33936e2246ff05b59d58Tyler Gunn                    serviceType, callType);
406a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            profile.setCallExtraInt(ImsCallProfile.EXTRA_OIR, clirMode);
407a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
408a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ImsCall imsCall = mImsManager.makeCall(mServiceId, profile,
409a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    callees, mImsCallListener);
410a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            conn.setImsCall(imsCall);
411ea8cb63201520592011a92849ad3661d22776c87Andrew Lee
412288268d5528e0df03f348e303954813cb188c55bRekha Kumar            setVideoCallProvider(conn, imsCall);
413a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (ImsException e) {
414a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            loge("dialInternal : " + e);
415a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            conn.setDisconnectCause(DisconnectCause.ERROR_UNSPECIFIED);
416a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            sendEmptyMessageDelayed(EVENT_HANGUP_PENDINGMO, TIMEOUT_HANGUP_PENDINGMO);
417ea8cb63201520592011a92849ad3661d22776c87Andrew Lee        } catch (RemoteException e) {
418a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
419a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
420a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4212999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn    /**
4222999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn     * Accepts a call with the specified video state.  The video state is the video state that the
4232999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn     * user has agreed upon in the InCall UI.
4242999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn     *
4252999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn     * @param videoState The video State
4262999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn     * @throws CallStateException
4272999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn     */
4282999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn    void acceptCall (int videoState) throws CallStateException {
429a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("acceptCall");
430a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
431a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mForegroundCall.getState().isAlive()
432a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                && mBackgroundCall.getState().isAlive()) {
433a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException("cannot accept call");
434a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
435a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
436a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if ((mRingingCall.getState() == ImsPhoneCall.State.WAITING)
437a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                && mForegroundCall.getState().isAlive()) {
438a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            setMute(false);
439288268d5528e0df03f348e303954813cb188c55bRekha Kumar            // Cache video state for pending MT call.
440288268d5528e0df03f348e303954813cb188c55bRekha Kumar            mPendingCallVideoState = videoState;
441a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            switchWaitingOrHoldingAndActive();
442a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else if (mRingingCall.getState().isRinging()) {
443a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("acceptCall: incoming...");
444a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            // Always unmute when answering a new call
445a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            setMute(false);
446a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            try {
447a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ImsCall imsCall = mRingingCall.getImsCall();
448a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (imsCall != null) {
4492999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn                    imsCall.accept(ImsCallProfile.getCallTypeFromVideoState(videoState));
450a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                } else {
451a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    throw new CallStateException("no valid ims call");
452a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
453a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } catch (ImsException e) {
454a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                throw new CallStateException("cannot accept call");
455a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
456a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else {
457a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException("phone not ringing");
458a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
459a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
460a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
461a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void
462a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    rejectCall () throws CallStateException {
463a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("rejectCall");
464a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
465a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mRingingCall.getState().isRinging()) {
466a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            hangup(mRingingCall);
467a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else {
468a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException("phone not ringing");
469a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
470a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
471a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
472a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void
473a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    switchWaitingOrHoldingAndActive() throws CallStateException {
474a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("switchWaitingOrHoldingAndActive");
475a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
476a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mRingingCall.getState() == ImsPhoneCall.State.INCOMING) {
477a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException("cannot be in the incoming state");
478a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
479a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
480a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mForegroundCall.getState() == ImsPhoneCall.State.ACTIVE) {
481a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ImsCall imsCall = mForegroundCall.getImsCall();
482a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (imsCall == null) {
483a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                throw new CallStateException("no ims call");
484a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
485a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
486276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // Swap the ImsCalls pointed to by the foreground and background ImsPhoneCalls.
487276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // If hold or resume later fails, we will swap them back.
488276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            mSwitchingFgAndBgCalls = true;
489276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            mCallExpectedToResume = mBackgroundCall.getImsCall();
490a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mForegroundCall.switchWith(mBackgroundCall);
491a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
492276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // Hold the foreground call; once the foreground call is held, the background call will
493276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // be resumed.
494a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            try {
495a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                imsCall.hold();
496a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } catch (ImsException e) {
497a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mForegroundCall.switchWith(mBackgroundCall);
498a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                throw new CallStateException(e.getMessage());
499a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
500a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else if (mBackgroundCall.getState() == ImsPhoneCall.State.HOLDING) {
501a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            resumeWaitingOrHolding();
502a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
503a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
504a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
505a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void
506a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    conference() {
507a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("conference");
508a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
509a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsCall fgImsCall = mForegroundCall.getImsCall();
510a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (fgImsCall == null) {
511a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("conference no foreground ims call");
512a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return;
513a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
514a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
515a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsCall bgImsCall = mBackgroundCall.getImsCall();
516a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (bgImsCall == null) {
517a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("conference no background ims call");
518a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return;
519a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
520a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
521fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn        // Keep track of the connect time of the earliest call so that it can be set on the
522fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn        // {@code ImsConference} when it is created.
523fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn        long conferenceConnectTime = Math.min(mForegroundCall.getEarliestConnectTime(),
524fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn                mBackgroundCall.getEarliestConnectTime());
525fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn        ImsPhoneConnection foregroundConnection = mForegroundCall.getFirstConnection();
526fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn        if (foregroundConnection != null) {
527fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn            foregroundConnection.setConferenceConnectTime(conferenceConnectTime);
528fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn        }
529fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn
530a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
531a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            fgImsCall.merge(bgImsCall);
532a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (ImsException e) {
533a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("conference " + e.getMessage());
534a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
535a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
536a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
537a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void
538a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    explicitCallTransfer() {
539a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        //TODO : implement
540a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
541a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
542a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void
543a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    clearDisconnected() {
544a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("clearDisconnected");
545a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
546a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        internalClearDisconnected();
547a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
548a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        updatePhoneState();
549a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.notifyPreciseCallStateChanged();
550a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
551a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
552a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    boolean
553a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    canConference() {
554a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mForegroundCall.getState() == ImsPhoneCall.State.ACTIVE
555a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && mBackgroundCall.getState() == ImsPhoneCall.State.HOLDING
556a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && !mBackgroundCall.isFull()
557a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && !mForegroundCall.isFull();
558a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
559a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
560a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    boolean
561a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    canDial() {
562a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean ret;
563a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        int serviceState = mPhone.getServiceState().getState();
564a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        String disableCall = SystemProperties.get(
565a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                TelephonyProperties.PROPERTY_DISABLE_CALL, "false");
566a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
567a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ret = (serviceState != ServiceState.STATE_POWER_OFF)
568a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && mPendingMO == null
569a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && !mRingingCall.isRinging()
570a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && !disableCall.equals("true")
571a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && (!mForegroundCall.getState().isAlive()
572a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    || !mBackgroundCall.getState().isAlive());
573a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
574a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return ret;
575a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
576a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
577a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    boolean
578a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    canTransfer() {
579a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mForegroundCall.getState() == ImsPhoneCall.State.ACTIVE
580a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && mBackgroundCall.getState() == ImsPhoneCall.State.HOLDING;
581a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
582a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
583a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Private Instance Methods
584a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
585a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void
586a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    internalClearDisconnected() {
587a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mRingingCall.clearDisconnected();
588a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mForegroundCall.clearDisconnected();
589a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mBackgroundCall.clearDisconnected();
590a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mHandoverCall.clearDisconnected();
591a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
592a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
593a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void
594a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    updatePhoneState() {
595a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        PhoneConstants.State oldState = mState;
596a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
597a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mRingingCall.isRinging()) {
598a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mState = PhoneConstants.State.RINGING;
599a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else if (mPendingMO != null ||
600a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                !(mForegroundCall.isIdle() && mBackgroundCall.isIdle())) {
601a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mState = PhoneConstants.State.OFFHOOK;
602a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else {
603a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mState = PhoneConstants.State.IDLE;
604a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
605a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
606a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mState == PhoneConstants.State.IDLE && oldState != mState) {
607a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mVoiceCallEndedRegistrants.notifyRegistrants(
608a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    new AsyncResult(null, null, null));
609a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else if (oldState == PhoneConstants.State.IDLE && oldState != mState) {
610a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mVoiceCallStartedRegistrants.notifyRegistrants (
611a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    new AsyncResult(null, null, null));
612a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
613a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
614a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("updatePhoneState oldState=" + oldState + ", newState=" + mState);
615a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
616a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mState != oldState) {
617a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.notifyPhoneStateChanged();
618a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
619a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
620a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
621a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void
622a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    handleRadioNotAvailable() {
623a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // handlePollCalls will clear out its
624a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // call list when it gets the CommandException
625a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // error result from this
626a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pollCallsWhenSafe();
627a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
628a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
629a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void
630a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    dumpState() {
631a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        List l;
632a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
633a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("Phone State:" + mState);
634a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
635a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("Ringing call: " + mRingingCall.toString());
636a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
637a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        l = mRingingCall.getConnections();
638a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (int i = 0, s = l.size(); i < s; i++) {
639a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log(l.get(i).toString());
640a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
641a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
642a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("Foreground call: " + mForegroundCall.toString());
643a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
644a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        l = mForegroundCall.getConnections();
645a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (int i = 0, s = l.size(); i < s; i++) {
646a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log(l.get(i).toString());
647a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
648a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
649a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("Background call: " + mBackgroundCall.toString());
650a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
651a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        l = mBackgroundCall.getConnections();
652a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (int i = 0, s = l.size(); i < s; i++) {
653a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log(l.get(i).toString());
654a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
655a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
656a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
657a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
658a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Called from ImsPhone
659a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
660b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh    void setUiTTYMode(int uiTtyMode, Message onComplete) {
661b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh        try {
662f1099a9dfe0250a6b343de0646413db4034381deEtan Cohen            mImsManager.setUiTTYMode(mPhone.getContext(), mServiceId, uiTtyMode, onComplete);
663b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh        } catch (ImsException e) {
664b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh            loge("setTTYMode : " + e);
665b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh            mPhone.sendErrorResponse(onComplete, e);
666b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh        }
667b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh    }
668b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh
669d9aa1a75304b1c04c352198b9269f40a2a059f74Andrew Lee    /*package*/ void setMute(boolean mute) {
670a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mDesiredMute = mute;
671a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mForegroundCall.setMute(mute);
672a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
673a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
674d9aa1a75304b1c04c352198b9269f40a2a059f74Andrew Lee    /*package*/ boolean getMute() {
675a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mDesiredMute;
676a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
677a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
678d9aa1a75304b1c04c352198b9269f40a2a059f74Andrew Lee    /* package */ void sendDtmf(char c, Message result) {
679a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("sendDtmf");
680a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
681a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsCall imscall = mForegroundCall.getImsCall();
682a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (imscall != null) {
683d9aa1a75304b1c04c352198b9269f40a2a059f74Andrew Lee            imscall.sendDtmf(c, result);
684a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
685a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
686a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
687c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam    /*package*/ void
688c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam    startDtmf(char c) {
689c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        if (DBG) log("startDtmf");
690c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam
691c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        ImsCall imscall = mForegroundCall.getImsCall();
692c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        if (imscall != null) {
693c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam            imscall.startDtmf(c);
694c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        } else {
695c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam            loge("startDtmf : no foreground call");
696c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        }
697c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam    }
698c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam
699c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam    /*package*/ void
700c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam    stopDtmf() {
701c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        if (DBG) log("stopDtmf");
702c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam
703c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        ImsCall imscall = mForegroundCall.getImsCall();
704c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        if (imscall != null) {
705c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam            imscall.stopDtmf();
706c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        } else {
707c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam            loge("stopDtmf : no foreground call");
708c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        }
709c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam    }
710c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam
711a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Called from ImsPhoneConnection
712a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
713a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /*package*/ void
714a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    hangup (ImsPhoneConnection conn) throws CallStateException {
715a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("hangup connection");
716a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
717a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (conn.getOwner() != this) {
718a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException ("ImsPhoneConnection " + conn
719a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    + "does not belong to ImsPhoneCallTracker " + this);
720a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
721a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
722a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        hangup(conn.getCall());
723a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
724a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
725a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Called from ImsPhoneCall
726a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
727a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /* package */ void
728a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    hangup (ImsPhoneCall call) throws CallStateException {
729a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("hangup call");
730a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
731a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (call.getConnections().size() == 0) {
732a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException("no connections");
733a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
734a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
735a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsCall imsCall = call.getImsCall();
736a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean rejectCall = false;
737a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
738a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (call == mRingingCall) {
739a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (Phone.DEBUG_PHONE) log("(ringing) hangup incoming");
740a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            rejectCall = true;
741a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else if (call == mForegroundCall) {
742a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (call.isDialingOrAlerting()) {
743a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (Phone.DEBUG_PHONE) {
744a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    log("(foregnd) hangup dialing or alerting...");
745a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
746a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
747a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (Phone.DEBUG_PHONE) {
748a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    log("(foregnd) hangup foreground");
749a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
750a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //held call will be resumed by onCallTerminated
751a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
752a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else if (call == mBackgroundCall) {
753a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (Phone.DEBUG_PHONE) {
754a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("(backgnd) hangup waiting or background");
755a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
756a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else {
757ac82d4da0473991006a752e2337ccb93e85f0946Etan Cohen            throw new CallStateException ("ImsPhoneCall " + call +
758a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    "does not belong to ImsPhoneCallTracker " + this);
759a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
760a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
761a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        call.onHangupLocal();
762a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
763a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
764a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (imsCall != null) {
765a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (rejectCall) imsCall.reject(ImsReasonInfo.CODE_USER_DECLINE);
766a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                else imsCall.terminate(ImsReasonInfo.CODE_USER_TERMINATED);
767a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else if (mPendingMO != null && call == mForegroundCall) {
768a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // is holding a foreground call
769a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mPendingMO.update(null, ImsPhoneCall.State.DISCONNECTED);
770a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mPendingMO.onDisconnect();
771a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                removeConnection(mPendingMO);
772a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mPendingMO = null;
773a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                updatePhoneState();
774a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                removeMessages(EVENT_DIAL_PENDINGMO);
775a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
776a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (ImsException e) {
777a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException(e.getMessage());
778a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
779a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
780a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.notifyPreciseCallStateChanged();
781a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
782a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
78369e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com    void callEndCleanupHandOverCallIfAny() {
78469e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com        if (mHandoverCall.mConnections.size() > 0) {
78569e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com            if (DBG) log("callEndCleanupHandOverCallIfAny, mHandoverCall.mConnections="
78669e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com                    + mHandoverCall.mConnections);
78769e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com            mHandoverCall.mConnections.clear();
78869e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com            mState = PhoneConstants.State.IDLE;
78969e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com        }
79069e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com    }
79169e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com
792a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /* package */
793a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void resumeWaitingOrHolding() throws CallStateException {
794a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("resumeWaitingOrHolding");
795a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
796a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
797a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (mForegroundCall.getState().isAlive()) {
798a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //resume foreground call after holding background call
799a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //they were switched before holding
800a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ImsCall imsCall = mForegroundCall.getImsCall();
801a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (imsCall != null) imsCall.resume();
802a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else if (mRingingCall.getState() == ImsPhoneCall.State.WAITING) {
803a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //accept waiting call after holding background call
804a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ImsCall imsCall = mRingingCall.getImsCall();
805288268d5528e0df03f348e303954813cb188c55bRekha Kumar                if (imsCall != null) {
806288268d5528e0df03f348e303954813cb188c55bRekha Kumar                    imsCall.accept(
807288268d5528e0df03f348e303954813cb188c55bRekha Kumar                        ImsCallProfile.getCallTypeFromVideoState(mPendingCallVideoState));
808288268d5528e0df03f348e303954813cb188c55bRekha Kumar                }
809a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
810a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //Just resume background call.
811a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //To distinguish resuming call with swapping calls
812a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //we do not switch calls.here
813a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //ImsPhoneConnection.update will chnage the parent when completed
814a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ImsCall imsCall = mBackgroundCall.getImsCall();
815a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (imsCall != null) imsCall.resume();
816a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
817a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (ImsException e) {
818a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException(e.getMessage());
819a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
820a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
821a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
822a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /* package */
823a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void sendUSSD (String ussdString, Message response) {
824a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("sendUSSD");
825a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
826a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
827a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (mUssdSession != null) {
828a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mUssdSession.sendUssd(ussdString);
829a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                AsyncResult.forMessage(response, null, null);
830a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                response.sendToTarget();
831a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return;
832a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
833a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
834a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            String[] callees = new String[] { ussdString };
835a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ImsCallProfile profile = mImsManager.createCallProfile(mServiceId,
836a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    ImsCallProfile.SERVICE_TYPE_NORMAL, ImsCallProfile.CALL_TYPE_VOICE);
837a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            profile.setCallExtraInt(ImsCallProfile.EXTRA_DIALSTRING,
838a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    ImsCallProfile.DIALSTRING_USSD);
839a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
840a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mUssdSession = mImsManager.makeCall(mServiceId, profile,
841a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    callees, mImsUssdListener);
842a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (ImsException e) {
843a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            loge("sendUSSD : " + e);
844a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.sendErrorResponse(response, e);
845a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
846a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
847a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
848a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /* package */
849a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void cancelUSSD() {
850a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mUssdSession == null) return;
851a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
852a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
853a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mUssdSession.terminate(ImsReasonInfo.CODE_USER_TERMINATED);
854a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (ImsException e) {
855a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
856a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
857a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
858a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
859288268d5528e0df03f348e303954813cb188c55bRekha Kumar    private synchronized ImsPhoneConnection findConnection(final ImsCall imsCall) {
860a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (ImsPhoneConnection conn : mConnections) {
861a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (conn.getImsCall() == imsCall) {
862a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return conn;
863a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
864a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
865a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return null;
866a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
867a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
868a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private synchronized void removeConnection(ImsPhoneConnection conn) {
869a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mConnections.remove(conn);
870a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
871a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
872a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private synchronized void addConnection(ImsPhoneConnection conn) {
873a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mConnections.add(conn);
874a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
875a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
876a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void processCallStateChange(ImsCall imsCall, ImsPhoneCall.State state, int cause) {
8770db65ec818e58fb5b83a492e082db4536f3b83e0Tyler Gunn        if (DBG) log("processCallStateChange " + imsCall + " state=" + state + " cause=" + cause);
878a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
879a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (imsCall == null) return;
880a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
881a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean changed = false;
882a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsPhoneConnection conn = findConnection(imsCall);
883a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
884a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (conn == null) {
885a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            // TODO : what should be done?
886a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return;
887a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
888a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
889a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        changed = conn.update(imsCall, state);
890a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
891a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (state == ImsPhoneCall.State.DISCONNECTED) {
892a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            changed = conn.onDisconnect(cause) || changed;
893de2242679c927ed9c46fa42f40162b113e337112Omkar Kolangade            //detach the disconnected connections
894de2242679c927ed9c46fa42f40162b113e337112Omkar Kolangade            conn.getCall().detach(conn);
895a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            removeConnection(conn);
896a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
897a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
898a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (changed) {
899a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (conn.getCall() == mHandoverCall) return;
900a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            updatePhoneState();
901a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.notifyPreciseCallStateChanged();
902a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
903a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
904a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
905a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private int getDisconnectCauseFromReasonInfo(ImsReasonInfo reasonInfo) {
906a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        int cause = DisconnectCause.ERROR_UNSPECIFIED;
907a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
908a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        //int type = reasonInfo.getReasonType();
909a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        int code = reasonInfo.getCode();
910a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        switch (code) {
911a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_BAD_ADDRESS:
912a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_NOT_REACHABLE:
913a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.NUMBER_UNREACHABLE;
914a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
915a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_BUSY:
916a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.BUSY;
917a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
918a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_USER_TERMINATED:
919a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.LOCAL;
920a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
9213b2b1bd2293667d4de32920cdad2c19f77777e2fLibin.Tang@motorola.com            case ImsReasonInfo.CODE_LOCAL_CALL_DECLINE:
9223b2b1bd2293667d4de32920cdad2c19f77777e2fLibin.Tang@motorola.com                return DisconnectCause.INCOMING_REJECTED;
9233b2b1bd2293667d4de32920cdad2c19f77777e2fLibin.Tang@motorola.com
924a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE:
925a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.NORMAL;
926a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
927a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_REDIRECTED:
928a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_BAD_REQUEST:
929a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_FORBIDDEN:
930a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_NOT_ACCEPTABLE:
931a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_USER_REJECTED:
932a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_GLOBAL_ERROR:
933a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.SERVER_ERROR;
934a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
935a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_SERVICE_UNAVAILABLE:
936a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_NOT_FOUND:
937a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_SERVER_ERROR:
938a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.SERVER_UNREACHABLE;
939a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
940a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_NETWORK_ROAMING:
941a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_NETWORK_IP_CHANGED:
942a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN:
943a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE:
944a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED:
945a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_NETWORK_NO_LTE_COVERAGE:
946a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_NETWORK_NO_SERVICE:
947a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_CALL_VCC_ON_PROGRESSING:
948a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.OUT_OF_SERVICE;
949a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
950a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_REQUEST_TIMEOUT:
951a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_TIMEOUT_1XX_WAITING:
952a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_TIMEOUT_NO_ANSWER:
953a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE:
954a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.TIMED_OUT;
955a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
956a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_LOW_BATTERY:
957a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_POWER_OFF:
958a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.POWER_OFF;
959a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
960a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            default:
961a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
962a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
963a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return cause;
964a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
965a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
966a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
967a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * Listen to the IMS call state change
968a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
969a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ImsCall.Listener mImsCallListener = new ImsCall.Listener() {
970a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
971a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallProgressing(ImsCall imsCall) {
972a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallProgressing");
973a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
974a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPendingMO = null;
975a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            processCallStateChange(imsCall, ImsPhoneCall.State.ALERTING,
976a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    DisconnectCause.NOT_DISCONNECTED);
977a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
978a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
979a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
980a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallStarted(ImsCall imsCall) {
981a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallStarted");
982a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
983a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPendingMO = null;
984a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            processCallStateChange(imsCall, ImsPhoneCall.State.ACTIVE,
985a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    DisconnectCause.NOT_DISCONNECTED);
986a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
987a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
988288268d5528e0df03f348e303954813cb188c55bRekha Kumar        @Override
989288268d5528e0df03f348e303954813cb188c55bRekha Kumar        public void onCallUpdated(ImsCall imsCall) {
990288268d5528e0df03f348e303954813cb188c55bRekha Kumar            if (DBG) log("onCallUpdated");
991288268d5528e0df03f348e303954813cb188c55bRekha Kumar            if (imsCall == null) {
992288268d5528e0df03f348e303954813cb188c55bRekha Kumar                return;
993288268d5528e0df03f348e303954813cb188c55bRekha Kumar            }
994288268d5528e0df03f348e303954813cb188c55bRekha Kumar            ImsPhoneConnection conn = findConnection(imsCall);
995288268d5528e0df03f348e303954813cb188c55bRekha Kumar            if (conn != null) {
996288268d5528e0df03f348e303954813cb188c55bRekha Kumar                processCallStateChange(imsCall, conn.getCall().mState,
997288268d5528e0df03f348e303954813cb188c55bRekha Kumar                        DisconnectCause.NOT_DISCONNECTED);
998288268d5528e0df03f348e303954813cb188c55bRekha Kumar            }
999288268d5528e0df03f348e303954813cb188c55bRekha Kumar        }
1000288268d5528e0df03f348e303954813cb188c55bRekha Kumar
1001a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        /**
1002a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         * onCallStartFailed will be invoked when:
1003a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         * case 1) Dialing fails
1004a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         * case 2) Ringing call is disconnected by local or remote user
1005a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         */
1006a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1007a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallStartFailed(ImsCall imsCall, ImsReasonInfo reasonInfo) {
1008a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallStartFailed reasonCode=" + reasonInfo.getCode());
1009a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1010a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (mPendingMO != null) {
1011a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // To initiate dialing circuit-switched call
1012a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (reasonInfo.getCode() == ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED
1013a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        && mBackgroundCall.getState() == ImsPhoneCall.State.IDLE
1014a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        && mRingingCall.getState() == ImsPhoneCall.State.IDLE) {
1015a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mForegroundCall.detach(mPendingMO);
1016a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    removeConnection(mPendingMO);
1017a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingMO.finalize();
1018a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingMO = null;
1019a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPhone.initiateSilentRedial();
1020a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    return;
1021990c42d788cb2f39cd7a6ddd97e5ebdefb298f75Libin.Tang@motorola.com                } else {
1022990c42d788cb2f39cd7a6ddd97e5ebdefb298f75Libin.Tang@motorola.com                    int cause = getDisconnectCauseFromReasonInfo(reasonInfo);
1023990c42d788cb2f39cd7a6ddd97e5ebdefb298f75Libin.Tang@motorola.com                    processCallStateChange(imsCall, ImsPhoneCall.State.DISCONNECTED, cause);
1024a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1025a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mPendingMO = null;
1026a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1027a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1028a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1029a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1030a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallTerminated(ImsCall imsCall, ImsReasonInfo reasonInfo) {
1031a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallTerminated reasonCode=" + reasonInfo.getCode());
1032a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1033a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ImsPhoneCall.State oldState = mForegroundCall.getState();
1034bc0406859056e2de6d36cbddf39e15fcfa8155b0Libin.Tang@motorola.com            int cause = getDisconnectCauseFromReasonInfo(reasonInfo);
1035bc0406859056e2de6d36cbddf39e15fcfa8155b0Libin.Tang@motorola.com            ImsPhoneConnection conn = findConnection(imsCall);
1036bc0406859056e2de6d36cbddf39e15fcfa8155b0Libin.Tang@motorola.com            if (DBG) log("cause = " + cause + " conn = " + conn);
1037bc0406859056e2de6d36cbddf39e15fcfa8155b0Libin.Tang@motorola.com
103817e77849f88cf20dc5a28aeede66b839fbbdb831Uma Maheswari Ramalingam            if (conn != null && conn.isIncoming() && conn.getConnectTime() == 0) {
10393b2b1bd2293667d4de32920cdad2c19f77777e2fLibin.Tang@motorola.com                // Missed
10403b2b1bd2293667d4de32920cdad2c19f77777e2fLibin.Tang@motorola.com                if (cause == DisconnectCause.NORMAL) {
1041bc0406859056e2de6d36cbddf39e15fcfa8155b0Libin.Tang@motorola.com                    cause = DisconnectCause.INCOMING_MISSED;
104217e77849f88cf20dc5a28aeede66b839fbbdb831Uma Maheswari Ramalingam                }
10435fbf6bed80437e092a93e6137de56e6b409910b1Etan Cohen                if (DBG) log("Incoming connection of 0 connect time detected - translated cause = "
10445fbf6bed80437e092a93e6137de56e6b409910b1Etan Cohen                        + cause);
1045f1227d71324a4d1916c3fd441ca688cc76129583Libin.Tang@motorola.com
1046bc0406859056e2de6d36cbddf39e15fcfa8155b0Libin.Tang@motorola.com            }
1047f885059bcd0c294e9830bfe5aeb16974c0717fa3Andrew Lee
1048f885059bcd0c294e9830bfe5aeb16974c0717fa3Andrew Lee            if (cause == DisconnectCause.NORMAL && conn != null && conn.getImsCall().isMerged()) {
1049f885059bcd0c294e9830bfe5aeb16974c0717fa3Andrew Lee                // Call was terminated while it is merged instead of a remote disconnect.
1050f885059bcd0c294e9830bfe5aeb16974c0717fa3Andrew Lee                cause = DisconnectCause.IMS_MERGED_SUCCESSFULLY;
1051f885059bcd0c294e9830bfe5aeb16974c0717fa3Andrew Lee            }
1052f885059bcd0c294e9830bfe5aeb16974c0717fa3Andrew Lee
1053bc0406859056e2de6d36cbddf39e15fcfa8155b0Libin.Tang@motorola.com            processCallStateChange(imsCall, ImsPhoneCall.State.DISCONNECTED, cause);
1054a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1055a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1056a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1057a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallHeld(ImsCall imsCall) {
1058a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallHeld");
1059a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1060a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            synchronized (mSyncHold) {
1061a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ImsPhoneCall.State oldState = mBackgroundCall.getState();
1062a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                processCallStateChange(imsCall, ImsPhoneCall.State.HOLDING,
1063a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        DisconnectCause.NOT_DISCONNECTED);
1064c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn
1065c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                // Note: If we're performing a switchWaitingOrHoldingAndActive, the call to
1066c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                // processCallStateChange above may have caused the mBackgroundCall and
1067c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                // mForegroundCall references below to change meaning.  Watch out for this if you
1068c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                // are reading through this code.
1069a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (oldState == ImsPhoneCall.State.ACTIVE) {
1070276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                    // Note: This case comes up when we have just held a call in response to a
1071276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                    // switchWaitingOrHoldingAndActive.  We now need to resume the background call.
1072276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                    // The EVENT_RESUME_BACKGROUND causes resumeWaitingOrHolding to be called.
1073a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    if ((mForegroundCall.getState() == ImsPhoneCall.State.HOLDING)
1074a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            || (mRingingCall.getState() == ImsPhoneCall.State.WAITING)) {
10750db65ec818e58fb5b83a492e082db4536f3b83e0Tyler Gunn
1076f1227d71324a4d1916c3fd441ca688cc76129583Libin.Tang@motorola.com                            sendEmptyMessage(EVENT_RESUME_BACKGROUND);
1077a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    } else {
1078a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        //when multiple connections belong to background call,
1079a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        //only the first callback reaches here
1080a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        //otherwise the oldState is already HOLDING
1081a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        if (mPendingMO != null) {
1082a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            sendEmptyMessage(EVENT_DIAL_PENDINGMO);
1083a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        }
1084c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn
1085c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                        // In this case there will be no call resumed, so we can assume that we
1086c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                        // are done switching fg and bg calls now.
1087c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                        // This may happen if there is no BG call and we are holding a call so that
1088c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                        // we can dial another one.
1089c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                        mSwitchingFgAndBgCalls = false;
1090a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    }
1091a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1092a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1093a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1094a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1095a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1096a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallHoldFailed(ImsCall imsCall, ImsReasonInfo reasonInfo) {
1097a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallHoldFailed reasonCode=" + reasonInfo.getCode());
1098a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1099a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            synchronized (mSyncHold) {
1100a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ImsPhoneCall.State bgState = mBackgroundCall.getState();
1101a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (reasonInfo.getCode() == ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED) {
1102a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    // disconnected while processing hold
1103a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    if (mPendingMO != null) {
1104a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        sendEmptyMessage(EVENT_DIAL_PENDINGMO);
1105a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    }
1106a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                } else if (bgState == ImsPhoneCall.State.ACTIVE) {
1107a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mForegroundCall.switchWith(mBackgroundCall);
1108a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1109a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    if (mPendingMO != null) {
1110a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        mPendingMO.setDisconnectCause(DisconnectCause.ERROR_UNSPECIFIED);
1111a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        sendEmptyMessageDelayed(EVENT_HANGUP_PENDINGMO, TIMEOUT_HANGUP_PENDINGMO);
1112a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    }
1113a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1114a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1115a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1116a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1117a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1118a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallResumed(ImsCall imsCall) {
1119a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallResumed");
1120a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1121276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // If we are the in midst of swapping FG and BG calls and the call we end up resuming
1122276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // is not the one we expected, we likely had a resume failure and we need to swap the
1123276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // FG and BG calls back.
1124276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            if (mSwitchingFgAndBgCalls && imsCall != mCallExpectedToResume) {
1125276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                mForegroundCall.switchWith(mBackgroundCall);
1126276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                mSwitchingFgAndBgCalls = false;
1127276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                mCallExpectedToResume = null;
1128276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            }
1129a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            processCallStateChange(imsCall, ImsPhoneCall.State.ACTIVE,
1130a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    DisconnectCause.NOT_DISCONNECTED);
1131a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1132a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1133a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1134a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallResumeFailed(ImsCall imsCall, ImsReasonInfo reasonInfo) {
1135a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            // TODO : What should be done?
1136276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // If we are in the midst of swapping the FG and BG calls and we got a resume fail, we
1137276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // need to swap back the FG and BG calls.
1138276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            if (mSwitchingFgAndBgCalls && imsCall == mCallExpectedToResume) {
1139276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                mForegroundCall.switchWith(mBackgroundCall);
1140276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                mCallExpectedToResume = null;
1141276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                mSwitchingFgAndBgCalls = false;
1142276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            }
1143276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            mPhone.notifySuppServiceFailed(Phone.SuppService.RESUME);
1144a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1145a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1146a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1147a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallResumeReceived(ImsCall imsCall) {
1148a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallResumeReceived");
1149a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1150a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (mOnHoldToneStarted) {
1151a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mPhone.stopOnHoldTone();
1152a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mOnHoldToneStarted = false;
1153a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1154a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1155a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1156a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1157a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallHoldReceived(ImsCall imsCall) {
1158a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallHoldReceived");
1159a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1160a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ImsPhoneConnection conn = findConnection(imsCall);
1161a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (conn != null && conn.getState() == ImsPhoneCall.State.ACTIVE) {
1162a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (!mOnHoldToneStarted && ImsPhoneCall.isLocalTone(imsCall)) {
1163a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPhone.startOnHoldTone();
1164a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mOnHoldToneStarted = true;
1165a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1166a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1167a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1168a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1169a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1170288268d5528e0df03f348e303954813cb188c55bRekha Kumar        public void onCallMerged(final ImsCall call, boolean swapCalls) {
1171a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallMerged");
1172a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1173a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mForegroundCall.merge(mBackgroundCall, mForegroundCall.getState());
1174fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn            if (swapCalls) {
1175fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn                try {
1176fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn                    switchWaitingOrHoldingAndActive();
1177fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn                } catch (CallStateException e) {
1178fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn                    if (Phone.DEBUG_PHONE) {
1179fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn                        loge("Failed swap fg and bg calls on merge exception=" + e);
1180fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn                    }
1181fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn                }
1182fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn            }
1183288268d5528e0df03f348e303954813cb188c55bRekha Kumar            // TODO Temporary code. Remove the try-catch block from the runnable once thread
1184288268d5528e0df03f348e303954813cb188c55bRekha Kumar            // synchronization is fixed.
1185288268d5528e0df03f348e303954813cb188c55bRekha Kumar            Runnable r = new Runnable() {
1186288268d5528e0df03f348e303954813cb188c55bRekha Kumar                @Override
1187288268d5528e0df03f348e303954813cb188c55bRekha Kumar                public void run() {
1188288268d5528e0df03f348e303954813cb188c55bRekha Kumar                    try {
1189288268d5528e0df03f348e303954813cb188c55bRekha Kumar                        final ImsPhoneConnection conn = findConnection(call);
1190288268d5528e0df03f348e303954813cb188c55bRekha Kumar                        log("onCallMerged: ImsPhoneConnection=" + conn);
1191288268d5528e0df03f348e303954813cb188c55bRekha Kumar                        log("onCallMerged: CurrentVideoProvider=" + conn.getVideoProvider());
1192288268d5528e0df03f348e303954813cb188c55bRekha Kumar                        setVideoCallProvider(conn, call);
1193288268d5528e0df03f348e303954813cb188c55bRekha Kumar                        log("onCallMerged: CurrentVideoProvider=" + conn.getVideoProvider());
1194288268d5528e0df03f348e303954813cb188c55bRekha Kumar                    } catch (Exception e) {
1195288268d5528e0df03f348e303954813cb188c55bRekha Kumar                        loge("onCallMerged: exception " + e);
1196288268d5528e0df03f348e303954813cb188c55bRekha Kumar                    }
1197288268d5528e0df03f348e303954813cb188c55bRekha Kumar                }
1198288268d5528e0df03f348e303954813cb188c55bRekha Kumar            };
1199288268d5528e0df03f348e303954813cb188c55bRekha Kumar
1200288268d5528e0df03f348e303954813cb188c55bRekha Kumar            ImsPhoneCallTracker.this.post(r);
1201288268d5528e0df03f348e303954813cb188c55bRekha Kumar
1202a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            updatePhoneState();
1203a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.notifyPreciseCallStateChanged();
1204a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1205a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1206a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1207a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallMergeFailed(ImsCall call, ImsReasonInfo reasonInfo) {
12084e47e27d1d2cbd8e533cdd2081c5bc8e51b79ad9Anthony Lee            if (DBG) log("onCallMergeFailed reasonInfo=" + reasonInfo);
120952c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee
121052c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            // TODO: the call to notifySuppServiceFailed throws up the "merge failed" dialog
121152c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            // We should move this into the InCallService so that it is handled appropriately
121252c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            // based on the user facing UI.
1213bd4d6093314c0d2afc4b4f69f352957d01d9bc58Uma Maheswari Ramalingam            mPhone.notifySuppServiceFailed(Phone.SuppService.CONFERENCE);
121452c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee
121552c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            // Start plumbing this even through Telecom so other components can take
121652c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            // appropriate action.
121752c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            ImsPhoneConnection conn = findConnection(call);
121852c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            if (conn != null) {
121952c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee                conn.onConferenceMergeFailed();
122052c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            }
1221a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1222fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn
1223fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn        /**
1224f53559f13dc272115f27f3b23955933da45ce127Tyler Gunn         * Called when the state of IMS conference participant(s) has changed.
1225fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn         *
1226fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn         * @param call the call object that carries out the IMS call.
1227f53559f13dc272115f27f3b23955933da45ce127Tyler Gunn         * @param participants the participant(s) and their new state information.
1228fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn         */
1229fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn        @Override
1230f53559f13dc272115f27f3b23955933da45ce127Tyler Gunn        public void onConferenceParticipantsStateChanged(ImsCall call,
1231f53559f13dc272115f27f3b23955933da45ce127Tyler Gunn                List<ConferenceParticipant> participants) {
1232f53559f13dc272115f27f3b23955933da45ce127Tyler Gunn            if (DBG) log("onConferenceParticipantsStateChanged");
1233fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn
1234fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn            ImsPhoneConnection conn = findConnection(call);
1235fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn            if (conn != null) {
1236f53559f13dc272115f27f3b23955933da45ce127Tyler Gunn                conn.updateConferenceParticipants(participants);
1237fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn            }
1238fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn        }
12396d91e295add44a5b7e611cb51401a20b3caa6571Pavel Zhamaitsiak
12406d91e295add44a5b7e611cb51401a20b3caa6571Pavel Zhamaitsiak        @Override
12416d91e295add44a5b7e611cb51401a20b3caa6571Pavel Zhamaitsiak        public void onCallSessionTtyModeReceived(ImsCall call, int mode) {
12426d91e295add44a5b7e611cb51401a20b3caa6571Pavel Zhamaitsiak            mPhone.onTtyModeReceived(mode);
12436d91e295add44a5b7e611cb51401a20b3caa6571Pavel Zhamaitsiak        }
12440ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar
12450ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        @Override
12460ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        public void onCallHandover(ImsCall imsCall, int srcAccessTech, int targetAccessTech,
12470ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            ImsReasonInfo reasonInfo) {
12480ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            if (DBG) {
12490ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar                log("onCallHandover ::  srcAccessTech=" + srcAccessTech + ", targetAccessTech=" +
12500ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar                    targetAccessTech + ", reasonInfo=" + reasonInfo);
12510ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            }
12520ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        }
12530ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar
12540ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        @Override
12550ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        public void onCallHandoverFailed(ImsCall imsCall, int srcAccessTech, int targetAccessTech,
12560ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            ImsReasonInfo reasonInfo) {
12570ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            if (DBG) {
12580ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar                log("onCallHandoverFailed :: srcAccessTech=" + srcAccessTech +
12590ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar                    ", targetAccessTech=" + targetAccessTech + ", reasonInfo=" + reasonInfo);
12600ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            }
12610ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        }
1262ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn
1263ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn        /**
1264ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn         * Handles a change to the multiparty state for an {@code ImsCall}.  Notifies the associated
1265ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn         * {@link ImsPhoneConnection} of the change.
1266ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn         *
1267ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn         * @param imsCall The IMS call.
1268ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn         * @param isMultiParty {@code true} if the call became multiparty, {@code false}
1269ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn         *      otherwise.
1270ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn         */
1271ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn        @Override
1272ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn        public void onMultipartyStateChanged(ImsCall imsCall, boolean isMultiParty) {
1273ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn            if (DBG) log("onMultipartyStateChanged to " + (isMultiParty ? "Y" : "N"));
1274ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn
1275ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn            ImsPhoneConnection conn = findConnection(imsCall);
1276ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn            if (conn != null) {
1277ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn                conn.updateMultipartyState(isMultiParty);
1278ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn            }
1279ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn        }
1280a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    };
1281a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1282a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
1283a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * Listen to the IMS call state change
1284a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
1285a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ImsCall.Listener mImsUssdListener = new ImsCall.Listener() {
1286a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1287a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallStarted(ImsCall imsCall) {
1288a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("mImsUssdListener onCallStarted");
1289a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1290a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (imsCall == mUssdSession) {
1291a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mPendingUssd != null) {
1292a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    AsyncResult.forMessage(mPendingUssd);
1293a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingUssd.sendToTarget();
1294a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingUssd = null;
1295a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1296a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1297a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1298a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1299a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1300a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallStartFailed(ImsCall imsCall, ImsReasonInfo reasonInfo) {
1301a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("mImsUssdListener onCallStartFailed reasonCode=" + reasonInfo.getCode());
1302a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1303a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            onCallTerminated(imsCall, reasonInfo);
1304a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1305a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1306a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1307a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallTerminated(ImsCall imsCall, ImsReasonInfo reasonInfo) {
1308a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("mImsUssdListener onCallTerminated reasonCode=" + reasonInfo.getCode());
1309a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1310a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (imsCall == mUssdSession) {
1311a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mUssdSession = null;
1312a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mPendingUssd != null) {
1313a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    CommandException ex =
1314a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            new CommandException(CommandException.Error.GENERIC_FAILURE);
1315a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    AsyncResult.forMessage(mPendingUssd, null, ex);
1316a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingUssd.sendToTarget();
1317a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingUssd = null;
1318a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1319a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1320a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            imsCall.close();
1321a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1322a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1323a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1324a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallUssdMessageReceived(ImsCall call,
1325a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                int mode, String ussdMessage) {
1326a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("mImsUssdListener onCallUssdMessageReceived mode=" + mode);
1327a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1328a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            int ussdMode = -1;
1329a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1330a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            switch(mode) {
1331a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                case ImsCall.USSD_MODE_REQUEST:
1332a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    ussdMode = CommandsInterface.USSD_MODE_REQUEST;
1333a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    break;
1334a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1335a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                case ImsCall.USSD_MODE_NOTIFY:
1336a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    ussdMode = CommandsInterface.USSD_MODE_NOTIFY;
1337a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    break;
1338a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1339a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1340a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.onIncomingUSSD(ussdMode, ussdMessage);
1341a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1342a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    };
1343a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1344a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
1345a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * Listen to the IMS service state change
1346a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     *
1347a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
1348a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ImsConnectionStateListener mImsConnectionStateListener =
1349a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        new ImsConnectionStateListener() {
1350a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1351a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onImsConnected() {
1352a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onImsConnected");
1353a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.setServiceState(ServiceState.STATE_IN_SERVICE);
1354bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com            mPhone.setImsRegistered(true);
1355a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1356a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1357a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
13580ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        public void onImsDisconnected(ImsReasonInfo imsReasonInfo) {
13590ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            if (DBG) log("onImsDisconnected imsReasonInfo=" + imsReasonInfo);
1360a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
1361bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com            mPhone.setImsRegistered(false);
136253f2bb9ba3118ff4c22e20ab3ad46ec97a72ac24Pavel Zhamaitsiak            mPhone.processDisconnectReason(imsReasonInfo);
1363a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1364a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1365a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
13660ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        public void onImsProgressing() {
13670ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            if (DBG) log("onImsProgressing");
13680ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        }
13690ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar
13700ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        @Override
1371a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onImsResumed() {
1372a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onImsResumed");
1373a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.setServiceState(ServiceState.STATE_IN_SERVICE);
1374a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1375a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1376a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1377a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onImsSuspended() {
1378a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onImsSuspended");
1379a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
1380a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1381cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com
1382cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com        @Override
1383cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com        public void onFeatureCapabilityChanged(int serviceClass,
1384cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com                int[] enabledFeatures, int[] disabledFeatures) {
1385cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com            if (serviceClass == ImsServiceClass.MMTEL) {
1386288268d5528e0df03f348e303954813cb188c55bRekha Kumar                boolean tmpIsVideoCallEnabled = isVideoCallEnabled();
138704b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                // Check enabledFeatures to determine capabilities. We ignore disabledFeatures.
138862a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com                for (int  i = ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE;
138962a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com                        i <= ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_WIFI; i++) {
139062a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com                    if (enabledFeatures[i] == i) {
139104b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                        // If the feature is set to its own integer value it is enabled.
139204b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                        if (DBG) log("onFeatureCapabilityChanged: i=" + i + ", value=true");
139362a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com                        mImsFeatureEnabled[i] = true;
139404b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                    } else if (enabledFeatures[i]
139504b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                            == ImsConfig.FeatureConstants.FEATURE_TYPE_UNKNOWN) {
139604b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                        // FEATURE_TYPE_UNKNOWN indicates that a feature is disabled.
139704b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                        if (DBG) log("onFeatureCapabilityChanged: i=" + i + ", value=false");
139862a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com                        mImsFeatureEnabled[i] = false;
139904b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                    } else {
140004b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                        // Feature has unknown state; it is not its own value or -1.
140104b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                        if (DBG) {
140204b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                            loge("onFeatureCapabilityChanged: i=" + i + ", unexpectedValue="
140304b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                                + enabledFeatures[i]);
140404b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                        }
140562a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com                    }
1406cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com                }
1407288268d5528e0df03f348e303954813cb188c55bRekha Kumar                if (tmpIsVideoCallEnabled != isVideoCallEnabled()) {
1408288268d5528e0df03f348e303954813cb188c55bRekha Kumar                    mPhone.notifyForVideoCapabilityChanged(isVideoCallEnabled());
1409288268d5528e0df03f348e303954813cb188c55bRekha Kumar                }
141004b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee
141104b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                // TODO: Use the ImsCallSession or ImsCallProfile to tell the initial Wifi state and
141204b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                // {@link ImsCallSession.Listener#callSessionHandover} to listen for changes to
141304b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                // wifi capability caused by a handover.
141404b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                if (DBG) log("onFeatureCapabilityChanged: isVowifiEnabled=" + isVowifiEnabled());
141504b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                for (ImsPhoneConnection connection : mConnections) {
141604b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                    connection.updateWifiState();
141704b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                }
1418e51d918511afab905399d9fda7f51442f15bd8a7Pavel Zhamaitsiak
1419e51d918511afab905399d9fda7f51442f15bd8a7Pavel Zhamaitsiak                mPhone.onFeatureCapabilityChanged();
1420cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com            }
142104b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee
142204b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee            if (DBG) log("onFeatureCapabilityChanged: mImsFeatureEnabled=" +  mImsFeatureEnabled);
1423cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com        }
1424a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    };
1425a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1426a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /* package */
1427a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    ImsUtInterface getUtInterface() throws ImsException {
1428a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mImsManager == null) {
1429a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new ImsException("no ims manager", ImsReasonInfo.CODE_UNSPECIFIED);
1430a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1431a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1432a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsUtInterface ut = mImsManager.getSupplementaryServiceConfiguration(mServiceId);
1433a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return ut;
1434a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1435a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
14364be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam    private void transferHandoverConnections(ImsPhoneCall call) {
14374be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        if (call.mConnections != null) {
14384be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            for (Connection c : call.mConnections) {
14394be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                c.mPreHandoverState = call.mState;
14404be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                log ("Connection state before handover is " + c.getStateBeforeHandover());
14414be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            }
14424be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        }
14434be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        if (mHandoverCall.mConnections == null ) {
14444be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            mHandoverCall.mConnections = call.mConnections;
14454be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        } else { // Multi-call SRVCC
14464be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            mHandoverCall.mConnections.addAll(call.mConnections);
14474be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        }
14484be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        if (mHandoverCall.mConnections != null) {
14494be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            if (call.getImsCall() != null) {
14504be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                call.getImsCall().close();
14514be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            }
14524be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            for (Connection c : mHandoverCall.mConnections) {
14534be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                ((ImsPhoneConnection)c).changeParent(mHandoverCall);
145452c193f0c615a9153a702ea2597217202613e413Libin.Tang@motorola.com                ((ImsPhoneConnection)c).releaseWakeLock();
14554be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            }
14564be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        }
14574be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        if (call.getState().isAlive()) {
14584be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            log ("Call is alive and state is " + call.mState);
14594be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            mHandoverCall.mState = call.mState;
14604be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        }
14614be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        call.mConnections.clear();
14624be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        call.mState = ImsPhoneCall.State.IDLE;
14634be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam    }
14644be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam
1465a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /* package */
1466a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void notifySrvccState(Call.SrvccState state) {
1467a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("notifySrvccState state=" + state);
1468a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1469a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mSrvccState = state;
1470a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1471a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mSrvccState == Call.SrvccState.COMPLETED) {
14724be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            transferHandoverConnections(mForegroundCall);
14734be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            transferHandoverConnections(mBackgroundCall);
14744be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            transferHandoverConnections(mRingingCall);
1475a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1476a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1477a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1478a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //****** Overridden from Handler
1479a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1480a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
1481a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void
1482a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    handleMessage (Message msg) {
1483a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        AsyncResult ar;
1484a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("handleMessage what=" + msg.what);
1485a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1486a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        switch (msg.what) {
1487a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case EVENT_HANGUP_PENDINGMO:
1488a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mPendingMO != null) {
1489a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingMO.onDisconnect();
1490a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    removeConnection(mPendingMO);
1491a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingMO = null;
1492a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1493a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1494a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                updatePhoneState();
1495a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mPhone.notifyPreciseCallStateChanged();
1496a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
1497a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case EVENT_RESUME_BACKGROUND:
1498a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                try {
1499a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    resumeWaitingOrHolding();
1500a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                } catch (CallStateException e) {
1501a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    if (Phone.DEBUG_PHONE) {
1502a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        loge("handleMessage EVENT_RESUME_BACKGROUND exception=" + e);
1503a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    }
1504a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1505a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
1506a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case EVENT_DIAL_PENDINGMO:
1507288268d5528e0df03f348e303954813cb188c55bRekha Kumar                dialInternal(mPendingMO, mClirMode, mPendingCallVideoState);
1508a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
150904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
151004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            case EVENT_EXIT_ECM_RESPONSE_CDMA:
151104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                // no matter the result, we still do the same here
151204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                if (pendingCallInEcm) {
1513288268d5528e0df03f348e303954813cb188c55bRekha Kumar                    dialInternal(mPendingMO, pendingCallClirMode,
1514288268d5528e0df03f348e303954813cb188c55bRekha Kumar                            mPendingCallVideoState);
151504e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                    pendingCallInEcm = false;
151604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                }
151704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                mPhone.unsetOnEcbModeExitResponse(this);
151804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                break;
1519a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1520a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1521a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1522a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
1523a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void log(String msg) {
1524a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.d(LOG_TAG, "[ImsPhoneCallTracker] " + msg);
1525a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1526a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1527a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void loge(String msg) {
1528a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.e(LOG_TAG, "[ImsPhoneCallTracker] " + msg);
1529a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1530a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1531a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
1532a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1533a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println("ImsPhoneCallTracker extends:");
1534a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        super.dump(fd, pw, args);
1535a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mVoiceCallEndedRegistrants=" + mVoiceCallEndedRegistrants);
1536a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mVoiceCallStartedRegistrants=" + mVoiceCallStartedRegistrants);
1537a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mRingingCall=" + mRingingCall);
1538a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mForegroundCall=" + mForegroundCall);
1539a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mBackgroundCall=" + mBackgroundCall);
1540a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mHandoverCall=" + mHandoverCall);
1541a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mPendingMO=" + mPendingMO);
1542a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        //pw.println(" mHangupPendingMO=" + mHangupPendingMO);
1543a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mPhone=" + mPhone);
1544a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mDesiredMute=" + mDesiredMute);
1545a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mState=" + mState);
1546a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1547a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1548a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
1549a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void handlePollCalls(AsyncResult ar) {
1550a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
155104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
155204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    /* package */
155304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    ImsEcbm getEcbmInterface() throws ImsException {
155404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        if (mImsManager == null) {
155504e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            throw new ImsException("no ims manager", ImsReasonInfo.CODE_UNSPECIFIED);
155604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        }
155704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
155804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        ImsEcbm ecbm = mImsManager.getEcbmInterface(mServiceId);
155904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        return ecbm;
156004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    }
156104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
156204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    public boolean isInEmergencyCall() {
156304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        return mIsInEmergencyCall;
156404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    }
1565cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com
1566cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com    public boolean isVolteEnabled() {
156762a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com        return mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE];
156862a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com    }
156962a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com
157062a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com    public boolean isVowifiEnabled() {
157162a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com        return mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI];
1572cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com    }
1573cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com
1574288268d5528e0df03f348e303954813cb188c55bRekha Kumar    public boolean isVideoCallEnabled() {
157562a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com        return (mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE]
157662a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com                || mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_WIFI]);
1577cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com    }
1578288268d5528e0df03f348e303954813cb188c55bRekha Kumar
1579b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com    @Override
1580b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com    public PhoneConstants.State getState() {
1581b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        return mState;
1582b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com    }
1583288268d5528e0df03f348e303954813cb188c55bRekha Kumar
1584288268d5528e0df03f348e303954813cb188c55bRekha Kumar    private void setVideoCallProvider(ImsPhoneConnection conn, ImsCall imsCall)
1585288268d5528e0df03f348e303954813cb188c55bRekha Kumar            throws RemoteException {
1586288268d5528e0df03f348e303954813cb188c55bRekha Kumar        IImsVideoCallProvider imsVideoCallProvider =
1587288268d5528e0df03f348e303954813cb188c55bRekha Kumar                imsCall.getCallSession().getVideoCallProvider();
1588288268d5528e0df03f348e303954813cb188c55bRekha Kumar        if (imsVideoCallProvider != null) {
1589288268d5528e0df03f348e303954813cb188c55bRekha Kumar            ImsVideoCallProviderWrapper imsVideoCallProviderWrapper =
1590288268d5528e0df03f348e303954813cb188c55bRekha Kumar                    new ImsVideoCallProviderWrapper(imsVideoCallProvider);
1591288268d5528e0df03f348e303954813cb188c55bRekha Kumar            conn.setVideoProvider(imsVideoCallProviderWrapper);
1592288268d5528e0df03f348e303954813cb188c55bRekha Kumar        }
1593288268d5528e0df03f348e303954813cb188c55bRekha Kumar    }
1594a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville}
1595