ImsPhoneCallTracker.java revision 2770b0f5449670eadab1d68ea8d5fa4788f4704a
1a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville/*
2a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * Copyright (C) 2013 The Android Open Source Project
3a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville *
4a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * Licensed under the Apache License, Version 2.0 (the "License");
5a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * you may not use this file except in compliance with the License.
6a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * You may obtain a copy of the License at
7a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville *
8a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville *      http://www.apache.org/licenses/LICENSE-2.0
9a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville *
10a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * Unless required by applicable law or agreed to in writing, software
11a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * distributed under the License is distributed on an "AS IS" BASIS,
12a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * See the License for the specific language governing permissions and
14a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * limitations under the License.
15a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville */
16a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
17a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savillepackage com.android.internal.telephony.imsphone;
18a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport java.io.FileDescriptor;
2004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport java.io.PrintWriter;
2104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport java.util.ArrayList;
2204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport java.util.List;
2304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
24a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.app.PendingIntent;
25a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.content.BroadcastReceiver;
26a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.content.Context;
27a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.content.Intent;
28a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.content.IntentFilter;
29a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.content.SharedPreferences;
30a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.AsyncResult;
31df0280231c51a24a0b66c24034827d7f73d6e1acSantos Cordonimport android.os.Bundle;
32a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Handler;
33a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Message;
34a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Registrant;
35a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.RegistrantList;
36ea8cb63201520592011a92849ad3661d22776c87Andrew Leeimport android.os.RemoteException;
37a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.SystemProperties;
38b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganeshimport android.provider.Settings;
3908e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganeshimport android.widget.Toast;
40a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.preference.PreferenceManager;
41fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunnimport android.telecom.ConferenceParticipant;
42dc2b5d1c32cad5269106d00fd106bd64097238f4Tyler Gunnimport android.telecom.VideoProfile;
43a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.DisconnectCause;
44a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.PhoneNumberUtils;
45a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.Rlog;
4604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport android.telephony.ServiceState;
47a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsCall;
4904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsCallProfile;
50cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.comimport com.android.ims.ImsConfig;
5104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsConnectionStateListener;
5204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsEcbm;
5304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsException;
5404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsManager;
5504e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsReasonInfo;
5604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsServiceClass;
5708e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganeshimport com.android.ims.ImsSuppServiceNotification;
5804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingamimport com.android.ims.ImsUtInterface;
59ea8cb63201520592011a92849ad3661d22776c87Andrew Leeimport com.android.ims.internal.IImsVideoCallProvider;
60ea8cb63201520592011a92849ad3661d22776c87Andrew Leeimport com.android.ims.internal.ImsVideoCallProviderWrapper;
61a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.Call;
62a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.CallStateException;
63a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.CallTracker;
64a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.CommandException;
65a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.CommandsInterface;
66a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.Connection;
67a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.Phone;
68a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.PhoneBase;
69a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.PhoneConstants;
70a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.TelephonyProperties;
7108e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganeshimport com.android.internal.telephony.gsm.SuppServiceNotification;
72a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
73a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville/**
74a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * {@hide}
75a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville */
76a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savillepublic final class ImsPhoneCallTracker extends CallTracker {
77a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    static final String LOG_TAG = "ImsPhoneCallTracker";
78a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
79a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private static final boolean DBG = true;
80a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
81707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    // When true, dumps the state of ImsPhoneCallTracker after changes to foreground and background
82707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    // calls.  This is helpful for debugging.
83707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    private static final boolean VERBOSE_STATE_LOGGING = false; /* stopship if true */
84707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn
85915b8a421c34b0872c96199d4390a70d5a76ed98Nathan Harold    //Indices map to ImsConfig.FeatureConstants
86164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati    private boolean[] mImsFeatureEnabled = {false, false, false, false, false, false};
87164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati    private final String[] mImsFeatureStrings = {"VoLTE", "ViLTE", "VoWiFi", "ViWiFi",
88164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati            "UTLTE", "UTWiFi"};
89cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com
90a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
91a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
92a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onReceive(Context context, Intent intent) {
93a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (intent.getAction().equals(ImsManager.ACTION_IMS_INCOMING_CALL)) {
94a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (DBG) log("onReceive : incoming call intent");
95a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
96a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mImsManager == null) return;
97a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
98a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mServiceId < 0) return;
99a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
100a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                try {
101a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    // Network initiated USSD will be treated by mImsUssdListener
102a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    boolean isUssd = intent.getBooleanExtra(ImsManager.EXTRA_USSD, false);
103a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    if (isUssd) {
104a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        if (DBG) log("onReceive : USSD");
105a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        mUssdSession = mImsManager.takeCall(mServiceId, intent, mImsUssdListener);
106a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        if (mUssdSession != null) {
1072999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn                            mUssdSession.accept(ImsCallProfile.CALL_TYPE_VOICE);
108a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        }
109a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        return;
110a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    }
111a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
11208e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    boolean isUnknown = intent.getBooleanExtra(ImsManager.EXTRA_IS_UNKNOWN_CALL,
11308e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                            false);
11408e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    if (DBG) {
11508e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                        log("onReceive : isUnknown = " + isUnknown +
11608e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                                " fg = " + mForegroundCall.getState() +
11708e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                                " bg = " + mBackgroundCall.getState());
11808e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    }
11908e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh
12008e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    // Normal MT/Unknown call
121a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    ImsCall imsCall = mImsManager.takeCall(mServiceId, intent, mImsCallListener);
1226bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius                    ImsPhoneConnection conn = new ImsPhoneConnection(mPhone, imsCall,
12308e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                            ImsPhoneCallTracker.this,
12408e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                            (isUnknown? mForegroundCall: mRingingCall), isUnknown);
125a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    addConnection(conn);
126a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
127288268d5528e0df03f348e303954813cb188c55bRekha Kumar                    setVideoCallProvider(conn, imsCall);
128ea8cb63201520592011a92849ad3661d22776c87Andrew Lee
12908e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    if (isUnknown) {
13008e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                        mPhone.notifyUnknownConnection(conn);
13108e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    } else {
13208e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                        if ((mForegroundCall.getState() != ImsPhoneCall.State.IDLE) ||
13308e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                                (mBackgroundCall.getState() != ImsPhoneCall.State.IDLE)) {
13408e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                            conn.update(imsCall, ImsPhoneCall.State.WAITING);
13508e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                        }
136a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
13708e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                        mPhone.notifyNewRingingConnection(conn);
13808e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                        mPhone.notifyIncomingRing();
13908e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    }
140a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
141a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    updatePhoneState();
142a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPhone.notifyPreciseCallStateChanged();
143a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                } catch (ImsException e) {
144a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    loge("onReceive : exception " + e);
145ea8cb63201520592011a92849ad3661d22776c87Andrew Lee                } catch (RemoteException e) {
146a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
147a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
148a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
149a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    };
150a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
151a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Constants
152a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
153a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    static final int MAX_CONNECTIONS = 7;
154a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    static final int MAX_CONNECTIONS_PER_CALL = 5;
155a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
156a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private static final int EVENT_HANGUP_PENDINGMO = 18;
157a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private static final int EVENT_RESUME_BACKGROUND = 19;
158a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private static final int EVENT_DIAL_PENDINGMO = 20;
159a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
160a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private static final int TIMEOUT_HANGUP_PENDINGMO = 500;
161a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
162a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Instance Variables
163a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ArrayList<ImsPhoneConnection> mConnections = new ArrayList<ImsPhoneConnection>();
164a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private RegistrantList mVoiceCallEndedRegistrants = new RegistrantList();
165a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private RegistrantList mVoiceCallStartedRegistrants = new RegistrantList();
166a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
167707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    final ImsPhoneCall mRingingCall = new ImsPhoneCall(this, ImsPhoneCall.CONTEXT_RINGING);
168707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    final ImsPhoneCall mForegroundCall = new ImsPhoneCall(this, ImsPhoneCall.CONTEXT_FOREGROUND);
169707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    final ImsPhoneCall mBackgroundCall = new ImsPhoneCall(this, ImsPhoneCall.CONTEXT_BACKGROUND);
170707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    final ImsPhoneCall mHandoverCall = new ImsPhoneCall(this, ImsPhoneCall.CONTEXT_HANDOVER);
171a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
172a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ImsPhoneConnection mPendingMO;
173a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private int mClirMode = CommandsInterface.CLIR_DEFAULT;
174a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private Object mSyncHold = new Object();
175a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
176a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ImsCall mUssdSession = null;
177a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private Message mPendingUssd = null;
178a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
179a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    ImsPhone mPhone;
180a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
181a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private boolean mDesiredMute = false;    // false = mute off
182a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private boolean mOnHoldToneStarted = false;
183a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
184a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    PhoneConstants.State mState = PhoneConstants.State.IDLE;
185a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
186a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ImsManager mImsManager;
187a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private int mServiceId = -1;
188a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
189a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private Call.SrvccState mSrvccState = Call.SrvccState.NONE;
190a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
19104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    private boolean mIsInEmergencyCall = false;
19204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
19304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    private int pendingCallClirMode;
194288268d5528e0df03f348e303954813cb188c55bRekha Kumar    private int mPendingCallVideoState;
195c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn    private Bundle mPendingIntentExtras;
19604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    private boolean pendingCallInEcm = false;
197276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn    private boolean mSwitchingFgAndBgCalls = false;
198276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn    private ImsCall mCallExpectedToResume = null;
19904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
200a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Events
201a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
202a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
203a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Constructors
204a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
205a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    ImsPhoneCallTracker(ImsPhone phone) {
206a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        this.mPhone = phone;
207a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
208a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        IntentFilter intentfilter = new IntentFilter();
209a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        intentfilter.addAction(ImsManager.ACTION_IMS_INCOMING_CALL);
210a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getContext().registerReceiver(mReceiver, intentfilter);
211a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
212a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Thread t = new Thread() {
213a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            public void run() {
214a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                getImsService();
215a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
216a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        };
217a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        t.start();
218a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
219a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
220a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private PendingIntent createIncomingCallPendingIntent() {
221a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Intent intent = new Intent(ImsManager.ACTION_IMS_INCOMING_CALL);
222a89314bcc94c43512299131609feea0c2c8167cfLibin.Tang@motorola.com        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
223a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
224a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                PendingIntent.FLAG_UPDATE_CURRENT);
225a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
226a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
227a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void getImsService() {
228a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("getImsService");
22953dde7e076954c250e55d156cc1df1202c3a8a9eEtan Cohen        mImsManager = ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId());
230a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
231a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mServiceId = mImsManager.open(ImsServiceClass.MMTEL,
232a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    createIncomingCallPendingIntent(),
233a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mImsConnectionStateListener);
23404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
23504e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            // Get the ECBM interface and set IMSPhone's listener object for notifications
23604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            getEcbmInterface().setEcbmStateListener(mPhone.mImsEcbmStateListener);
23704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            if (mPhone.isInEcm()) {
23804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                // Call exit ECBM which will invoke onECBMExited
23904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                mPhone.exitEmergencyCallbackMode();
24004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            }
241b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh            int mPreferredTtyMode = Settings.Secure.getInt(
242b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh                mPhone.getContext().getContentResolver(),
243b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh                Settings.Secure.PREFERRED_TTY_MODE,
244b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh                Phone.TTY_MODE_OFF);
245f1099a9dfe0250a6b343de0646413db4034381deEtan Cohen           mImsManager.setUiTTYMode(mPhone.getContext(), mServiceId, mPreferredTtyMode, null);
246b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh
247a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (ImsException e) {
248a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            loge("getImsService: " + e);
249a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            //Leave mImsManager as null, then CallStateException will be thrown when dialing
250a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mImsManager = null;
251a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
252a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
253a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
254a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void dispose() {
255a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("dispose");
256a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mRingingCall.dispose();
257a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mBackgroundCall.dispose();
258a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mForegroundCall.dispose();
259a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mHandoverCall.dispose();
260a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
261a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        clearDisconnected();
262a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.getContext().unregisterReceiver(mReceiver);
263a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
264a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
265a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
266a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void finalize() {
267a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("ImsPhoneCallTracker finalized");
268a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
269a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
270a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Instance Methods
271a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
272a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Public Methods
273a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
274a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void registerForVoiceCallStarted(Handler h, int what, Object obj) {
275a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Registrant r = new Registrant(h, what, obj);
276a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mVoiceCallStartedRegistrants.add(r);
277a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
278a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
279a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
280a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void unregisterForVoiceCallStarted(Handler h) {
281a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mVoiceCallStartedRegistrants.remove(h);
282a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
283a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
284a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
285a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void registerForVoiceCallEnded(Handler h, int what, Object obj) {
286a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Registrant r = new Registrant(h, what, obj);
287a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mVoiceCallEndedRegistrants.add(r);
288a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
289a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
290a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
291a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void unregisterForVoiceCallEnded(Handler h) {
292a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mVoiceCallEndedRegistrants.remove(h);
293a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
294a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
295a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    Connection
296df0280231c51a24a0b66c24034827d7f73d6e1acSantos Cordon    dial(String dialString, int videoState, Bundle intentExtras) throws CallStateException {
297a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
298a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        int oirMode = sp.getInt(PhoneBase.CLIR_KEY, CommandsInterface.CLIR_DEFAULT);
299df0280231c51a24a0b66c24034827d7f73d6e1acSantos Cordon        return dial(dialString, oirMode, videoState, intentExtras);
300a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
301a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
302a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
303a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * oirMode is one of the CLIR_ constants
304a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
305a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    synchronized Connection
306df0280231c51a24a0b66c24034827d7f73d6e1acSantos Cordon    dial(String dialString, int clirMode, int videoState, Bundle intentExtras)
307df0280231c51a24a0b66c24034827d7f73d6e1acSantos Cordon            throws CallStateException {
30804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        boolean isPhoneInEcmMode = SystemProperties.getBoolean(
30904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                TelephonyProperties.PROPERTY_INECM_MODE, false);
31004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        boolean isEmergencyNumber = PhoneNumberUtils.isEmergencyNumber(dialString);
31104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
312a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("dial clirMode=" + clirMode);
313a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
314a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // note that this triggers call state changed notif
315a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        clearDisconnected();
316a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
317a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mImsManager == null) {
318a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException("service not available");
319a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
320a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
321a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!canDial()) {
322a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException("cannot dial in current state");
323a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
324a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
32504e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        if (isPhoneInEcmMode && isEmergencyNumber) {
32604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            handleEcmTimer(ImsPhone.CANCEL_ECM_TIMER);
32704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        }
32804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
329a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean holdBeforeDial = false;
330a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
331a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // The new call must be assigned to the foreground call.
332a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // That call must be idle, so place anything that's
333a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // there on hold
334a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mForegroundCall.getState() == ImsPhoneCall.State.ACTIVE) {
335a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (mBackgroundCall.getState() != ImsPhoneCall.State.IDLE) {
336a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //we should have failed in !canDial() above before we get here
337a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                throw new CallStateException("cannot dial in current state");
338a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
339a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            // foreground call is empty for the newly dialed connection
340a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            holdBeforeDial = true;
341288268d5528e0df03f348e303954813cb188c55bRekha Kumar            // Cache the video state for pending MO call.
342288268d5528e0df03f348e303954813cb188c55bRekha Kumar            mPendingCallVideoState = videoState;
343c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn            mPendingIntentExtras = intentExtras;
344a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            switchWaitingOrHoldingAndActive();
345a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
346a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
347a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsPhoneCall.State fgState = ImsPhoneCall.State.IDLE;
348a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsPhoneCall.State bgState = ImsPhoneCall.State.IDLE;
349a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
350a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mClirMode = clirMode;
351a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
352a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        synchronized (mSyncHold) {
353a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (holdBeforeDial) {
354a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                fgState = mForegroundCall.getState();
355a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                bgState = mBackgroundCall.getState();
356a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
357a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //holding foreground call failed
358a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (fgState == ImsPhoneCall.State.ACTIVE) {
359a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    throw new CallStateException("cannot dial in current state");
360a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
361a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
362a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //holding foreground call succeeded
363a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (bgState == ImsPhoneCall.State.HOLDING) {
364a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    holdBeforeDial = false;
365a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
366a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
367a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3686bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius            mPendingMO = new ImsPhoneConnection(mPhone,
369a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    checkForTestEmergencyNumber(dialString), this, mForegroundCall);
370a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
371a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        addConnection(mPendingMO);
372a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
373a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (!holdBeforeDial) {
37404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            if ((!isPhoneInEcmMode) || (isPhoneInEcmMode && isEmergencyNumber)) {
375c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn                dialInternal(mPendingMO, clirMode, videoState, intentExtras);
37604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            } else {
37704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                try {
37804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                    getEcbmInterface().exitEmergencyCallbackMode();
37904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                } catch (ImsException e) {
38004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                    e.printStackTrace();
38104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                    throw new CallStateException("service not available");
38204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                }
38304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                mPhone.setOnEcbModeExitResponse(this, EVENT_EXIT_ECM_RESPONSE_CDMA, null);
38404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                pendingCallClirMode = clirMode;
385288268d5528e0df03f348e303954813cb188c55bRekha Kumar                mPendingCallVideoState = videoState;
38604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                pendingCallInEcm = true;
38704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            }
388a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
389a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
390a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        updatePhoneState();
391a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.notifyPreciseCallStateChanged();
392a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
393a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mPendingMO;
394a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
395a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
39604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    private void handleEcmTimer(int action) {
39704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        mPhone.handleTimerInEmergencyCallbackMode(action);
39804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        switch (action) {
39904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            case ImsPhone.CANCEL_ECM_TIMER:
40004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                break;
40104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            case ImsPhone.RESTART_ECM_TIMER:
40204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                break;
40304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            default:
40404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                log("handleEcmTimer, unsupported action " + action);
40504e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        }
40604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    }
40704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
408c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn    private void dialInternal(ImsPhoneConnection conn, int clirMode, int videoState,
409c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn            Bundle intentExtras) {
410c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn
411a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (conn == null) {
412a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return;
413a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
414a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
415a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (conn.getAddress()== null || conn.getAddress().length() == 0
416a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                || conn.getAddress().indexOf(PhoneNumberUtils.WILD) >= 0) {
417a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            // Phone number is invalid
418a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            conn.setDisconnectCause(DisconnectCause.INVALID_NUMBER);
419a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            sendEmptyMessageDelayed(EVENT_HANGUP_PENDINGMO, TIMEOUT_HANGUP_PENDINGMO);
420a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return;
421a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
422a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
423a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // Always unmute when initiating a new call
424a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        setMute(false);
425a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        int serviceType = PhoneNumberUtils.isEmergencyNumber(conn.getAddress()) ?
4266bbcbfd62c9aa5787e7c33936e2246ff05b59d58Tyler Gunn                ImsCallProfile.SERVICE_TYPE_EMERGENCY : ImsCallProfile.SERVICE_TYPE_NORMAL;
42764e62340aae85179a6468ccac4a401900eb4dc2fTyler Gunn        int callType = ImsCallProfile.getCallTypeFromVideoState(videoState);
42864e62340aae85179a6468ccac4a401900eb4dc2fTyler Gunn        //TODO(vt): Is this sufficient?  At what point do we know the video state of the call?
42964e62340aae85179a6468ccac4a401900eb4dc2fTyler Gunn        conn.setVideoState(videoState);
430a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
431a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
432a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            String[] callees = new String[] { conn.getAddress() };
433a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ImsCallProfile profile = mImsManager.createCallProfile(mServiceId,
4346bbcbfd62c9aa5787e7c33936e2246ff05b59d58Tyler Gunn                    serviceType, callType);
435a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            profile.setCallExtraInt(ImsCallProfile.EXTRA_OIR, clirMode);
436a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
437c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn            // Translate call subject intent-extra from Telecom-specific extra key to the
438c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn            // ImsCallProfile key.
439c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn            if (intentExtras != null) {
440c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn                if (intentExtras.containsKey(android.telecom.TelecomManager.EXTRA_CALL_SUBJECT)) {
441c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn                    intentExtras.putString(ImsCallProfile.EXTRA_DISPLAY_TEXT,
442c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn                            intentExtras.getString(
443c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn                                    android.telecom.TelecomManager.EXTRA_CALL_SUBJECT));
444c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn                }
445c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn
446c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn                // Pack the OEM-specific call extras.
447c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn                profile.mCallExtras.putBundle(ImsCallProfile.EXTRA_OEM_EXTRAS, intentExtras);
448c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn
449c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn                // NOTE: Extras to be sent over the network are packed into the
450c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn                // intentExtras individually, with uniquely defined keys.
451c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn                // These key-value pairs are processed by IMS Service before
452c02d6b7f2f48a291b42892424e6858f71c3d84a9Tyler Gunn                // being sent to the lower layers/to the network.
453c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn            }
454c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn
455a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ImsCall imsCall = mImsManager.makeCall(mServiceId, profile,
456a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    callees, mImsCallListener);
457a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            conn.setImsCall(imsCall);
458ea8cb63201520592011a92849ad3661d22776c87Andrew Lee
459288268d5528e0df03f348e303954813cb188c55bRekha Kumar            setVideoCallProvider(conn, imsCall);
460a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (ImsException e) {
461a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            loge("dialInternal : " + e);
462a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            conn.setDisconnectCause(DisconnectCause.ERROR_UNSPECIFIED);
463a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            sendEmptyMessageDelayed(EVENT_HANGUP_PENDINGMO, TIMEOUT_HANGUP_PENDINGMO);
464ea8cb63201520592011a92849ad3661d22776c87Andrew Lee        } catch (RemoteException e) {
465a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
466a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
467a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
4682999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn    /**
4692999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn     * Accepts a call with the specified video state.  The video state is the video state that the
4702999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn     * user has agreed upon in the InCall UI.
4712999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn     *
4722999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn     * @param videoState The video State
4732999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn     * @throws CallStateException
4742999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn     */
4752999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn    void acceptCall (int videoState) throws CallStateException {
476a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("acceptCall");
477a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
478a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mForegroundCall.getState().isAlive()
479a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                && mBackgroundCall.getState().isAlive()) {
480a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException("cannot accept call");
481a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
482a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
483a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if ((mRingingCall.getState() == ImsPhoneCall.State.WAITING)
484a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                && mForegroundCall.getState().isAlive()) {
485a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            setMute(false);
486288268d5528e0df03f348e303954813cb188c55bRekha Kumar            // Cache video state for pending MT call.
487288268d5528e0df03f348e303954813cb188c55bRekha Kumar            mPendingCallVideoState = videoState;
488a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            switchWaitingOrHoldingAndActive();
489a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else if (mRingingCall.getState().isRinging()) {
490a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("acceptCall: incoming...");
491a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            // Always unmute when answering a new call
492a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            setMute(false);
493a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            try {
494a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ImsCall imsCall = mRingingCall.getImsCall();
495a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (imsCall != null) {
4962999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn                    imsCall.accept(ImsCallProfile.getCallTypeFromVideoState(videoState));
497a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                } else {
498a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    throw new CallStateException("no valid ims call");
499a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
500a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } catch (ImsException e) {
501a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                throw new CallStateException("cannot accept call");
502a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
503a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else {
504a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException("phone not ringing");
505a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
506a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
507a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
508a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void
509a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    rejectCall () throws CallStateException {
510a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("rejectCall");
511a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
512a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mRingingCall.getState().isRinging()) {
513a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            hangup(mRingingCall);
514a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else {
515a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException("phone not ringing");
516a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
517a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
518a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
519007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam
520007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam    private void switchAfterConferenceSuccess() {
521007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam        if (DBG) log("switchAfterConferenceSuccess fg =" + mForegroundCall.getState() +
522007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam                ", bg = " + mBackgroundCall.getState());
523007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam
524007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam        if (mBackgroundCall.getState() == ImsPhoneCall.State.HOLDING) {
525007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            log("switchAfterConferenceSuccess");
526007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            mForegroundCall.switchWith(mBackgroundCall);
527007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam        }
528007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam    }
529007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam
530a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void
531a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    switchWaitingOrHoldingAndActive() throws CallStateException {
532a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("switchWaitingOrHoldingAndActive");
533a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
534a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mRingingCall.getState() == ImsPhoneCall.State.INCOMING) {
535a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException("cannot be in the incoming state");
536a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
537a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
538a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mForegroundCall.getState() == ImsPhoneCall.State.ACTIVE) {
539a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ImsCall imsCall = mForegroundCall.getImsCall();
540a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (imsCall == null) {
541a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                throw new CallStateException("no ims call");
542a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
543a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
544276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // Swap the ImsCalls pointed to by the foreground and background ImsPhoneCalls.
545276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // If hold or resume later fails, we will swap them back.
546276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            mSwitchingFgAndBgCalls = true;
547276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            mCallExpectedToResume = mBackgroundCall.getImsCall();
548a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mForegroundCall.switchWith(mBackgroundCall);
549a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
550276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // Hold the foreground call; once the foreground call is held, the background call will
551276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // be resumed.
552a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            try {
553a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                imsCall.hold();
554707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn
555707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                // If there is no background call to resume, then don't expect there to be a switch.
556707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                if (mCallExpectedToResume == null) {
557707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                    mSwitchingFgAndBgCalls = false;
558707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                }
559a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } catch (ImsException e) {
560a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mForegroundCall.switchWith(mBackgroundCall);
561a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                throw new CallStateException(e.getMessage());
562a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
563a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else if (mBackgroundCall.getState() == ImsPhoneCall.State.HOLDING) {
564a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            resumeWaitingOrHolding();
565a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
566a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
567a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
568a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void
569a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    conference() {
570a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("conference");
571a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
572a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsCall fgImsCall = mForegroundCall.getImsCall();
573a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (fgImsCall == null) {
574a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("conference no foreground ims call");
575a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return;
576a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
577a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
578a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsCall bgImsCall = mBackgroundCall.getImsCall();
579a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (bgImsCall == null) {
580a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("conference no background ims call");
581a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return;
582a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
583a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
584fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn        // Keep track of the connect time of the earliest call so that it can be set on the
585fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn        // {@code ImsConference} when it is created.
5867ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn        long foregroundConnectTime = mForegroundCall.getEarliestConnectTime();
5877ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn        long backgroundConnectTime = mBackgroundCall.getEarliestConnectTime();
5887ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn        long conferenceConnectTime;
5897ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn        if (foregroundConnectTime > 0 && backgroundConnectTime > 0) {
5907ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn            conferenceConnectTime = Math.min(mForegroundCall.getEarliestConnectTime(),
5917ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn                    mBackgroundCall.getEarliestConnectTime());
5927ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn            log("conference - using connect time = " + conferenceConnectTime);
5937ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn        } else if (foregroundConnectTime > 0) {
5947ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn            log("conference - bg call connect time is 0; using fg = " + foregroundConnectTime);
5957ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn            conferenceConnectTime = foregroundConnectTime;
5967ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn        } else {
5977ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn            log("conference - fg call connect time is 0; using bg = " + backgroundConnectTime);
5987ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn            conferenceConnectTime = backgroundConnectTime;
5997ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn        }
6007ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn
601fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn        ImsPhoneConnection foregroundConnection = mForegroundCall.getFirstConnection();
602fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn        if (foregroundConnection != null) {
603fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn            foregroundConnection.setConferenceConnectTime(conferenceConnectTime);
604fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn        }
605fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn
606a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
607a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            fgImsCall.merge(bgImsCall);
608a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (ImsException e) {
609a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log("conference " + e.getMessage());
610a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
611a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
612a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
613a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void
614a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    explicitCallTransfer() {
615a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        //TODO : implement
616a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
617a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
618a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void
619a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    clearDisconnected() {
620a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("clearDisconnected");
621a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
622a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        internalClearDisconnected();
623a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
624a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        updatePhoneState();
625a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.notifyPreciseCallStateChanged();
626a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
627a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
628a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    boolean
629a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    canConference() {
630a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mForegroundCall.getState() == ImsPhoneCall.State.ACTIVE
631a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && mBackgroundCall.getState() == ImsPhoneCall.State.HOLDING
632a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && !mBackgroundCall.isFull()
633a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && !mForegroundCall.isFull();
634a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
635a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
636a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    boolean
637a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    canDial() {
638a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean ret;
639a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        int serviceState = mPhone.getServiceState().getState();
640a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        String disableCall = SystemProperties.get(
641a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                TelephonyProperties.PROPERTY_DISABLE_CALL, "false");
642a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
643a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ret = (serviceState != ServiceState.STATE_POWER_OFF)
644a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && mPendingMO == null
645a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && !mRingingCall.isRinging()
646a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && !disableCall.equals("true")
647a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && (!mForegroundCall.getState().isAlive()
648a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    || !mBackgroundCall.getState().isAlive());
649a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
650a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return ret;
651a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
652a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
653a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    boolean
654a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    canTransfer() {
655a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mForegroundCall.getState() == ImsPhoneCall.State.ACTIVE
656a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            && mBackgroundCall.getState() == ImsPhoneCall.State.HOLDING;
657a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
658a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
659a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Private Instance Methods
660a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
661a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void
662a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    internalClearDisconnected() {
663a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mRingingCall.clearDisconnected();
664a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mForegroundCall.clearDisconnected();
665a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mBackgroundCall.clearDisconnected();
666a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mHandoverCall.clearDisconnected();
667a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
668a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
669a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void
670a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    updatePhoneState() {
671a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        PhoneConstants.State oldState = mState;
672a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
673a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mRingingCall.isRinging()) {
674a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mState = PhoneConstants.State.RINGING;
675a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else if (mPendingMO != null ||
676a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                !(mForegroundCall.isIdle() && mBackgroundCall.isIdle())) {
677a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mState = PhoneConstants.State.OFFHOOK;
678a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else {
679a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mState = PhoneConstants.State.IDLE;
680a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
681a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
682a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mState == PhoneConstants.State.IDLE && oldState != mState) {
683a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mVoiceCallEndedRegistrants.notifyRegistrants(
684a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    new AsyncResult(null, null, null));
685a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else if (oldState == PhoneConstants.State.IDLE && oldState != mState) {
686a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mVoiceCallStartedRegistrants.notifyRegistrants (
687a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    new AsyncResult(null, null, null));
688a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
689a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
690a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("updatePhoneState oldState=" + oldState + ", newState=" + mState);
691a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
692a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mState != oldState) {
693a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.notifyPhoneStateChanged();
694a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
695a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
696a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
697a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void
698a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    handleRadioNotAvailable() {
699a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // handlePollCalls will clear out its
700a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // call list when it gets the CommandException
701a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        // error result from this
702a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pollCallsWhenSafe();
703a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
704a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
705a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void
706a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    dumpState() {
707a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        List l;
708a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
709a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("Phone State:" + mState);
710a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
711a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("Ringing call: " + mRingingCall.toString());
712a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
713a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        l = mRingingCall.getConnections();
714a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (int i = 0, s = l.size(); i < s; i++) {
715a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log(l.get(i).toString());
716a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
717a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
718a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("Foreground call: " + mForegroundCall.toString());
719a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
720a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        l = mForegroundCall.getConnections();
721a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (int i = 0, s = l.size(); i < s; i++) {
722a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log(l.get(i).toString());
723a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
724a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
725a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        log("Background call: " + mBackgroundCall.toString());
726a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
727a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        l = mBackgroundCall.getConnections();
728a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (int i = 0, s = l.size(); i < s; i++) {
729a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            log(l.get(i).toString());
730a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
731a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
732a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
733a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
734a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Called from ImsPhone
735a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
736b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh    void setUiTTYMode(int uiTtyMode, Message onComplete) {
737b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh        try {
738f1099a9dfe0250a6b343de0646413db4034381deEtan Cohen            mImsManager.setUiTTYMode(mPhone.getContext(), mServiceId, uiTtyMode, onComplete);
739b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh        } catch (ImsException e) {
740b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh            loge("setTTYMode : " + e);
741b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh            mPhone.sendErrorResponse(onComplete, e);
742b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh        }
743b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh    }
744b7aff911e1106eb2eb16fd2bafae0ed8f4d4d4f7Shriram Ganesh
745d9aa1a75304b1c04c352198b9269f40a2a059f74Andrew Lee    /*package*/ void setMute(boolean mute) {
746a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mDesiredMute = mute;
747a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mForegroundCall.setMute(mute);
748a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
749a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
750d9aa1a75304b1c04c352198b9269f40a2a059f74Andrew Lee    /*package*/ boolean getMute() {
751a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mDesiredMute;
752a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
753a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
754d9aa1a75304b1c04c352198b9269f40a2a059f74Andrew Lee    /* package */ void sendDtmf(char c, Message result) {
755a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("sendDtmf");
756a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
757a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsCall imscall = mForegroundCall.getImsCall();
758a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (imscall != null) {
759d9aa1a75304b1c04c352198b9269f40a2a059f74Andrew Lee            imscall.sendDtmf(c, result);
760a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
761a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
762a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
763c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam    /*package*/ void
764c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam    startDtmf(char c) {
765c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        if (DBG) log("startDtmf");
766c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam
767c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        ImsCall imscall = mForegroundCall.getImsCall();
768c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        if (imscall != null) {
769c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam            imscall.startDtmf(c);
770c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        } else {
771c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam            loge("startDtmf : no foreground call");
772c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        }
773c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam    }
774c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam
775c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam    /*package*/ void
776c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam    stopDtmf() {
777c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        if (DBG) log("stopDtmf");
778c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam
779c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        ImsCall imscall = mForegroundCall.getImsCall();
780c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        if (imscall != null) {
781c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam            imscall.stopDtmf();
782c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        } else {
783c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam            loge("stopDtmf : no foreground call");
784c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam        }
785c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam    }
786c204cc0f515864b36187d60f6ab79af28885d36eUma Maheswari Ramalingam
787a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Called from ImsPhoneConnection
788a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
789a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /*package*/ void
790a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    hangup (ImsPhoneConnection conn) throws CallStateException {
791a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("hangup connection");
792a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
793a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (conn.getOwner() != this) {
794a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException ("ImsPhoneConnection " + conn
795a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    + "does not belong to ImsPhoneCallTracker " + this);
796a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
797a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
798a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        hangup(conn.getCall());
799a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
800a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
801a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Called from ImsPhoneCall
802a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
803a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /* package */ void
804a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    hangup (ImsPhoneCall call) throws CallStateException {
805a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("hangup call");
806a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
807a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (call.getConnections().size() == 0) {
808a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException("no connections");
809a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
810a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
811a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsCall imsCall = call.getImsCall();
812a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean rejectCall = false;
813a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
814a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (call == mRingingCall) {
815a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (Phone.DEBUG_PHONE) log("(ringing) hangup incoming");
816a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            rejectCall = true;
817a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else if (call == mForegroundCall) {
818a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (call.isDialingOrAlerting()) {
819a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (Phone.DEBUG_PHONE) {
820a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    log("(foregnd) hangup dialing or alerting...");
821a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
822a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
823a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (Phone.DEBUG_PHONE) {
824a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    log("(foregnd) hangup foreground");
825a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
826a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //held call will be resumed by onCallTerminated
827a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
828a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else if (call == mBackgroundCall) {
829a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (Phone.DEBUG_PHONE) {
830a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                log("(backgnd) hangup waiting or background");
831a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
832a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else {
833ac82d4da0473991006a752e2337ccb93e85f0946Etan Cohen            throw new CallStateException ("ImsPhoneCall " + call +
834a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    "does not belong to ImsPhoneCallTracker " + this);
835a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
836a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
837a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        call.onHangupLocal();
838a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
839a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
840a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (imsCall != null) {
841a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (rejectCall) imsCall.reject(ImsReasonInfo.CODE_USER_DECLINE);
842a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                else imsCall.terminate(ImsReasonInfo.CODE_USER_TERMINATED);
843a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else if (mPendingMO != null && call == mForegroundCall) {
844a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // is holding a foreground call
845a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mPendingMO.update(null, ImsPhoneCall.State.DISCONNECTED);
846a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mPendingMO.onDisconnect();
847a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                removeConnection(mPendingMO);
848a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mPendingMO = null;
849a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                updatePhoneState();
850a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                removeMessages(EVENT_DIAL_PENDINGMO);
851a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
852a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (ImsException e) {
853a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException(e.getMessage());
854a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
855a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
856a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mPhone.notifyPreciseCallStateChanged();
857a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
858a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
85969e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com    void callEndCleanupHandOverCallIfAny() {
86069e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com        if (mHandoverCall.mConnections.size() > 0) {
86169e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com            if (DBG) log("callEndCleanupHandOverCallIfAny, mHandoverCall.mConnections="
86269e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com                    + mHandoverCall.mConnections);
86369e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com            mHandoverCall.mConnections.clear();
86469e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com            mState = PhoneConstants.State.IDLE;
86569e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com        }
86669e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com    }
86769e989aceb5660b39932049daad2299f75f07201Libin.Tang@motorola.com
868a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /* package */
869a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void resumeWaitingOrHolding() throws CallStateException {
870a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("resumeWaitingOrHolding");
871a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
872a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
873a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (mForegroundCall.getState().isAlive()) {
874a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //resume foreground call after holding background call
875a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //they were switched before holding
876a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ImsCall imsCall = mForegroundCall.getImsCall();
877a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (imsCall != null) imsCall.resume();
878a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else if (mRingingCall.getState() == ImsPhoneCall.State.WAITING) {
879a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //accept waiting call after holding background call
880a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ImsCall imsCall = mRingingCall.getImsCall();
881288268d5528e0df03f348e303954813cb188c55bRekha Kumar                if (imsCall != null) {
882288268d5528e0df03f348e303954813cb188c55bRekha Kumar                    imsCall.accept(
883288268d5528e0df03f348e303954813cb188c55bRekha Kumar                        ImsCallProfile.getCallTypeFromVideoState(mPendingCallVideoState));
884288268d5528e0df03f348e303954813cb188c55bRekha Kumar                }
885a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else {
886a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //Just resume background call.
887a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //To distinguish resuming call with swapping calls
888a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //we do not switch calls.here
889a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                //ImsPhoneConnection.update will chnage the parent when completed
890a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ImsCall imsCall = mBackgroundCall.getImsCall();
891a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (imsCall != null) imsCall.resume();
892a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
893a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (ImsException e) {
894a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new CallStateException(e.getMessage());
895a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
896a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
897a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
898a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /* package */
899a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void sendUSSD (String ussdString, Message response) {
900a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("sendUSSD");
901a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
902a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
903a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (mUssdSession != null) {
904a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mUssdSession.sendUssd(ussdString);
905a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                AsyncResult.forMessage(response, null, null);
906a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                response.sendToTarget();
907a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return;
908a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
909a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
910a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            String[] callees = new String[] { ussdString };
911a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ImsCallProfile profile = mImsManager.createCallProfile(mServiceId,
912a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    ImsCallProfile.SERVICE_TYPE_NORMAL, ImsCallProfile.CALL_TYPE_VOICE);
913a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            profile.setCallExtraInt(ImsCallProfile.EXTRA_DIALSTRING,
914a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    ImsCallProfile.DIALSTRING_USSD);
915a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
916a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mUssdSession = mImsManager.makeCall(mServiceId, profile,
917a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    callees, mImsUssdListener);
918a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (ImsException e) {
919a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            loge("sendUSSD : " + e);
920a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.sendErrorResponse(response, e);
921a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
922a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
923a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
924a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /* package */
925a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void cancelUSSD() {
926a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mUssdSession == null) return;
927a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
928a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
929a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mUssdSession.terminate(ImsReasonInfo.CODE_USER_TERMINATED);
930a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (ImsException e) {
931a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
932a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
933a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
934a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
935288268d5528e0df03f348e303954813cb188c55bRekha Kumar    private synchronized ImsPhoneConnection findConnection(final ImsCall imsCall) {
936a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (ImsPhoneConnection conn : mConnections) {
937a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (conn.getImsCall() == imsCall) {
938a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return conn;
939a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
940a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
941a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return null;
942a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
943a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
944a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private synchronized void removeConnection(ImsPhoneConnection conn) {
945a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mConnections.remove(conn);
946a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
947a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
948a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private synchronized void addConnection(ImsPhoneConnection conn) {
949a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mConnections.add(conn);
950a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
951a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
952a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void processCallStateChange(ImsCall imsCall, ImsPhoneCall.State state, int cause) {
9530db65ec818e58fb5b83a492e082db4536f3b83e0Tyler Gunn        if (DBG) log("processCallStateChange " + imsCall + " state=" + state + " cause=" + cause);
954d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        // This method is called on onCallUpdate() where there is not necessarily a call state
955d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        // change. In these situations, we'll ignore the state related updates and only process
956d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        // the change in media capabilities (as expected).  The default is to not ignore state
957d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        // changes so we do not change existing behavior.
958d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        processCallStateChange(imsCall, state, cause, false /* do not ignore state update */);
959d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati    }
960d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati
961d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati    private void processCallStateChange(ImsCall imsCall, ImsPhoneCall.State state, int cause,
962d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati            boolean ignoreState) {
963d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        if (DBG) {
964d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati            log("processCallStateChange state=" + state + " cause=" + cause
965d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati                    + " ignoreState=" + ignoreState);
966d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        }
967a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
968a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (imsCall == null) return;
969a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
970a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean changed = false;
971a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsPhoneConnection conn = findConnection(imsCall);
972a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
973a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (conn == null) {
974a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            // TODO : what should be done?
975a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return;
976a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
977a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
978d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        // processCallStateChange is triggered for onCallUpdated as well.
979d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        // onCallUpdated should not modify the state of the call
980d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        // It should modify only other capabilities of call through updateMediaCapabilities
981d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        // State updates will be triggered through individual callbacks
982d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        // i.e. onCallHeld, onCallResume, etc and conn.update will be responsible for the update
983d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati        if (ignoreState) {
984d8413260e889d5b4db43e652304553ed29fa3e41Tyler Gunn            conn.updateMediaCapabilities(imsCall);
985d8413260e889d5b4db43e652304553ed29fa3e41Tyler Gunn            return;
986d8413260e889d5b4db43e652304553ed29fa3e41Tyler Gunn        }
987d8413260e889d5b4db43e652304553ed29fa3e41Tyler Gunn
988d8413260e889d5b4db43e652304553ed29fa3e41Tyler Gunn        changed = conn.update(imsCall, state);
989d8413260e889d5b4db43e652304553ed29fa3e41Tyler Gunn        if (state == ImsPhoneCall.State.DISCONNECTED) {
990d8413260e889d5b4db43e652304553ed29fa3e41Tyler Gunn            changed = conn.onDisconnect(cause) || changed;
991d8413260e889d5b4db43e652304553ed29fa3e41Tyler Gunn            //detach the disconnected connections
992d8413260e889d5b4db43e652304553ed29fa3e41Tyler Gunn            conn.getCall().detach(conn);
993d8413260e889d5b4db43e652304553ed29fa3e41Tyler Gunn            removeConnection(conn);
994a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
995a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
996a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (changed) {
997a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (conn.getCall() == mHandoverCall) return;
998a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            updatePhoneState();
999a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.notifyPreciseCallStateChanged();
1000a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1001a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1002a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1003a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private int getDisconnectCauseFromReasonInfo(ImsReasonInfo reasonInfo) {
1004a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        int cause = DisconnectCause.ERROR_UNSPECIFIED;
1005a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1006a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        //int type = reasonInfo.getReasonType();
1007a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        int code = reasonInfo.getCode();
1008a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        switch (code) {
1009a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_BAD_ADDRESS:
1010a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_NOT_REACHABLE:
1011a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.NUMBER_UNREACHABLE;
1012a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1013a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_BUSY:
1014a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.BUSY;
1015a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1016a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_USER_TERMINATED:
1017a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.LOCAL;
1018a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
10193b2b1bd2293667d4de32920cdad2c19f77777e2fLibin.Tang@motorola.com            case ImsReasonInfo.CODE_LOCAL_CALL_DECLINE:
10203b2b1bd2293667d4de32920cdad2c19f77777e2fLibin.Tang@motorola.com                return DisconnectCause.INCOMING_REJECTED;
10213b2b1bd2293667d4de32920cdad2c19f77777e2fLibin.Tang@motorola.com
1022a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE:
1023a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.NORMAL;
1024a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1025a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_REDIRECTED:
1026a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_BAD_REQUEST:
1027a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_FORBIDDEN:
1028a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_NOT_ACCEPTABLE:
1029a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_USER_REJECTED:
1030a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_GLOBAL_ERROR:
1031a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.SERVER_ERROR;
1032a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1033a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_SERVICE_UNAVAILABLE:
1034a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_NOT_FOUND:
1035a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_SERVER_ERROR:
1036a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.SERVER_UNREACHABLE;
1037a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1038a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_NETWORK_ROAMING:
1039a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_NETWORK_IP_CHANGED:
1040a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN:
1041a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE:
1042a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED:
1043a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_NETWORK_NO_LTE_COVERAGE:
1044a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_NETWORK_NO_SERVICE:
1045a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_CALL_VCC_ON_PROGRESSING:
1046a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.OUT_OF_SERVICE;
1047a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1048a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_SIP_REQUEST_TIMEOUT:
1049a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_TIMEOUT_1XX_WAITING:
1050a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_TIMEOUT_NO_ANSWER:
1051a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE:
1052a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.TIMED_OUT;
1053a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1054a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_LOW_BATTERY:
1055a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case ImsReasonInfo.CODE_LOCAL_POWER_OFF:
1056a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return DisconnectCause.POWER_OFF;
1057a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
105808e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            case ImsReasonInfo.CODE_FDN_BLOCKED:
105908e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                return DisconnectCause.FDN_BLOCKED;
1060a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            default:
1061a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1062a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1063a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return cause;
1064a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1065a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1066a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
1067a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * Listen to the IMS call state change
1068a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
1069a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ImsCall.Listener mImsCallListener = new ImsCall.Listener() {
1070a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1071a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallProgressing(ImsCall imsCall) {
1072a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallProgressing");
1073a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1074a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPendingMO = null;
1075a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            processCallStateChange(imsCall, ImsPhoneCall.State.ALERTING,
1076a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    DisconnectCause.NOT_DISCONNECTED);
1077a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1078a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1079a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1080a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallStarted(ImsCall imsCall) {
1081a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallStarted");
1082a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1083a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPendingMO = null;
1084a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            processCallStateChange(imsCall, ImsPhoneCall.State.ACTIVE,
1085a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    DisconnectCause.NOT_DISCONNECTED);
1086a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1087a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1088288268d5528e0df03f348e303954813cb188c55bRekha Kumar        @Override
1089288268d5528e0df03f348e303954813cb188c55bRekha Kumar        public void onCallUpdated(ImsCall imsCall) {
1090288268d5528e0df03f348e303954813cb188c55bRekha Kumar            if (DBG) log("onCallUpdated");
1091288268d5528e0df03f348e303954813cb188c55bRekha Kumar            if (imsCall == null) {
1092288268d5528e0df03f348e303954813cb188c55bRekha Kumar                return;
1093288268d5528e0df03f348e303954813cb188c55bRekha Kumar            }
1094288268d5528e0df03f348e303954813cb188c55bRekha Kumar            ImsPhoneConnection conn = findConnection(imsCall);
1095288268d5528e0df03f348e303954813cb188c55bRekha Kumar            if (conn != null) {
1096288268d5528e0df03f348e303954813cb188c55bRekha Kumar                processCallStateChange(imsCall, conn.getCall().mState,
1097d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati                        DisconnectCause.NOT_DISCONNECTED, true /*ignore state update*/);
1098288268d5528e0df03f348e303954813cb188c55bRekha Kumar            }
1099288268d5528e0df03f348e303954813cb188c55bRekha Kumar        }
1100288268d5528e0df03f348e303954813cb188c55bRekha Kumar
1101a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        /**
1102a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         * onCallStartFailed will be invoked when:
1103a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         * case 1) Dialing fails
1104a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         * case 2) Ringing call is disconnected by local or remote user
1105a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville         */
1106a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1107a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallStartFailed(ImsCall imsCall, ImsReasonInfo reasonInfo) {
1108a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallStartFailed reasonCode=" + reasonInfo.getCode());
1109a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1110a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (mPendingMO != null) {
1111a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                // To initiate dialing circuit-switched call
1112a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (reasonInfo.getCode() == ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED
1113a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        && mBackgroundCall.getState() == ImsPhoneCall.State.IDLE
1114a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        && mRingingCall.getState() == ImsPhoneCall.State.IDLE) {
1115a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mForegroundCall.detach(mPendingMO);
1116a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    removeConnection(mPendingMO);
1117a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingMO.finalize();
1118a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingMO = null;
1119a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPhone.initiateSilentRedial();
1120a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    return;
1121990c42d788cb2f39cd7a6ddd97e5ebdefb298f75Libin.Tang@motorola.com                } else {
11222770b0f5449670eadab1d68ea8d5fa4788f4704aSantos Cordon                    mPendingMO = null;
1123990c42d788cb2f39cd7a6ddd97e5ebdefb298f75Libin.Tang@motorola.com                    int cause = getDisconnectCauseFromReasonInfo(reasonInfo);
1124990c42d788cb2f39cd7a6ddd97e5ebdefb298f75Libin.Tang@motorola.com                    processCallStateChange(imsCall, ImsPhoneCall.State.DISCONNECTED, cause);
1125a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1126a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1127a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1128a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1129a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1130a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallTerminated(ImsCall imsCall, ImsReasonInfo reasonInfo) {
1131a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallTerminated reasonCode=" + reasonInfo.getCode());
1132a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1133a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ImsPhoneCall.State oldState = mForegroundCall.getState();
1134bc0406859056e2de6d36cbddf39e15fcfa8155b0Libin.Tang@motorola.com            int cause = getDisconnectCauseFromReasonInfo(reasonInfo);
1135bc0406859056e2de6d36cbddf39e15fcfa8155b0Libin.Tang@motorola.com            ImsPhoneConnection conn = findConnection(imsCall);
1136bc0406859056e2de6d36cbddf39e15fcfa8155b0Libin.Tang@motorola.com            if (DBG) log("cause = " + cause + " conn = " + conn);
1137bc0406859056e2de6d36cbddf39e15fcfa8155b0Libin.Tang@motorola.com
113817e77849f88cf20dc5a28aeede66b839fbbdb831Uma Maheswari Ramalingam            if (conn != null && conn.isIncoming() && conn.getConnectTime() == 0) {
11393b2b1bd2293667d4de32920cdad2c19f77777e2fLibin.Tang@motorola.com                // Missed
11403b2b1bd2293667d4de32920cdad2c19f77777e2fLibin.Tang@motorola.com                if (cause == DisconnectCause.NORMAL) {
1141bc0406859056e2de6d36cbddf39e15fcfa8155b0Libin.Tang@motorola.com                    cause = DisconnectCause.INCOMING_MISSED;
114208e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                } else {
114308e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    cause = DisconnectCause.INCOMING_REJECTED;
114417e77849f88cf20dc5a28aeede66b839fbbdb831Uma Maheswari Ramalingam                }
11455fbf6bed80437e092a93e6137de56e6b409910b1Etan Cohen                if (DBG) log("Incoming connection of 0 connect time detected - translated cause = "
11465fbf6bed80437e092a93e6137de56e6b409910b1Etan Cohen                        + cause);
1147f1227d71324a4d1916c3fd441ca688cc76129583Libin.Tang@motorola.com
1148bc0406859056e2de6d36cbddf39e15fcfa8155b0Libin.Tang@motorola.com            }
1149f885059bcd0c294e9830bfe5aeb16974c0717fa3Andrew Lee
1150f885059bcd0c294e9830bfe5aeb16974c0717fa3Andrew Lee            if (cause == DisconnectCause.NORMAL && conn != null && conn.getImsCall().isMerged()) {
1151f885059bcd0c294e9830bfe5aeb16974c0717fa3Andrew Lee                // Call was terminated while it is merged instead of a remote disconnect.
1152f885059bcd0c294e9830bfe5aeb16974c0717fa3Andrew Lee                cause = DisconnectCause.IMS_MERGED_SUCCESSFULLY;
1153f885059bcd0c294e9830bfe5aeb16974c0717fa3Andrew Lee            }
1154f885059bcd0c294e9830bfe5aeb16974c0717fa3Andrew Lee
1155bc0406859056e2de6d36cbddf39e15fcfa8155b0Libin.Tang@motorola.com            processCallStateChange(imsCall, ImsPhoneCall.State.DISCONNECTED, cause);
115608e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            if (mForegroundCall.getState() != ImsPhoneCall.State.ACTIVE) {
115708e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                if (mRingingCall.getState().isRinging()) {
115808e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    // Drop pending MO. We should address incoming call first
115908e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    mPendingMO = null;
116008e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                } else if (mPendingMO != null) {
116108e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                    sendEmptyMessage(EVENT_DIAL_PENDINGMO);
116208e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                }
116308e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            }
1164a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1165a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1166a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1167a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallHeld(ImsCall imsCall) {
1168707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            if (DBG) {
1169707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                if (mForegroundCall.getImsCall() == imsCall) {
1170707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                    log("onCallHeld (fg) " + imsCall);
1171707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                } else if (mBackgroundCall.getImsCall() == imsCall) {
1172707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                    log("onCallHeld (bg) " + imsCall);
1173707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                }
1174707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            }
1175a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1176a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            synchronized (mSyncHold) {
1177a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ImsPhoneCall.State oldState = mBackgroundCall.getState();
1178a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                processCallStateChange(imsCall, ImsPhoneCall.State.HOLDING,
1179a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        DisconnectCause.NOT_DISCONNECTED);
1180c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn
1181c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                // Note: If we're performing a switchWaitingOrHoldingAndActive, the call to
1182c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                // processCallStateChange above may have caused the mBackgroundCall and
1183c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                // mForegroundCall references below to change meaning.  Watch out for this if you
1184c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                // are reading through this code.
1185a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (oldState == ImsPhoneCall.State.ACTIVE) {
1186276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                    // Note: This case comes up when we have just held a call in response to a
1187276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                    // switchWaitingOrHoldingAndActive.  We now need to resume the background call.
1188276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                    // The EVENT_RESUME_BACKGROUND causes resumeWaitingOrHolding to be called.
1189a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    if ((mForegroundCall.getState() == ImsPhoneCall.State.HOLDING)
1190a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            || (mRingingCall.getState() == ImsPhoneCall.State.WAITING)) {
11910db65ec818e58fb5b83a492e082db4536f3b83e0Tyler Gunn
1192f1227d71324a4d1916c3fd441ca688cc76129583Libin.Tang@motorola.com                            sendEmptyMessage(EVENT_RESUME_BACKGROUND);
1193a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    } else {
1194a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        //when multiple connections belong to background call,
1195a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        //only the first callback reaches here
1196a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        //otherwise the oldState is already HOLDING
1197a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        if (mPendingMO != null) {
1198a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            sendEmptyMessage(EVENT_DIAL_PENDINGMO);
1199a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        }
1200c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn
1201c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                        // In this case there will be no call resumed, so we can assume that we
1202c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                        // are done switching fg and bg calls now.
1203c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                        // This may happen if there is no BG call and we are holding a call so that
1204c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                        // we can dial another one.
1205c7c2aff39afb425b34ea6cc17d172cc28f5ab4f0Tyler Gunn                        mSwitchingFgAndBgCalls = false;
1206a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    }
1207a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1208a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1209a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1210a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1211a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1212a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallHoldFailed(ImsCall imsCall, ImsReasonInfo reasonInfo) {
1213a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallHoldFailed reasonCode=" + reasonInfo.getCode());
1214a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1215a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            synchronized (mSyncHold) {
1216a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ImsPhoneCall.State bgState = mBackgroundCall.getState();
1217a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (reasonInfo.getCode() == ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED) {
1218a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    // disconnected while processing hold
1219a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    if (mPendingMO != null) {
1220a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        sendEmptyMessage(EVENT_DIAL_PENDINGMO);
1221a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    }
1222a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                } else if (bgState == ImsPhoneCall.State.ACTIVE) {
1223a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mForegroundCall.switchWith(mBackgroundCall);
1224a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1225a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    if (mPendingMO != null) {
1226a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        mPendingMO.setDisconnectCause(DisconnectCause.ERROR_UNSPECIFIED);
1227a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        sendEmptyMessageDelayed(EVENT_HANGUP_PENDINGMO, TIMEOUT_HANGUP_PENDINGMO);
1228a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    }
1229a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1230a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1231a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1232a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1233a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1234a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallResumed(ImsCall imsCall) {
1235a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallResumed");
1236a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1237276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // If we are the in midst of swapping FG and BG calls and the call we end up resuming
1238276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // is not the one we expected, we likely had a resume failure and we need to swap the
1239276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // FG and BG calls back.
1240276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            if (mSwitchingFgAndBgCalls && imsCall != mCallExpectedToResume) {
1241707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                if (DBG) {
1242707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                    log("onCallResumed : switching " + mForegroundCall + " with "
1243707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                            + mBackgroundCall);
1244707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                }
1245276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                mForegroundCall.switchWith(mBackgroundCall);
1246276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                mSwitchingFgAndBgCalls = false;
1247276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                mCallExpectedToResume = null;
1248276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            }
1249a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            processCallStateChange(imsCall, ImsPhoneCall.State.ACTIVE,
1250a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    DisconnectCause.NOT_DISCONNECTED);
1251a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1252a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1253a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1254a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallResumeFailed(ImsCall imsCall, ImsReasonInfo reasonInfo) {
1255276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // If we are in the midst of swapping the FG and BG calls and we got a resume fail, we
1256276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            // need to swap back the FG and BG calls.
1257276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            if (mSwitchingFgAndBgCalls && imsCall == mCallExpectedToResume) {
1258707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                if (DBG) {
1259707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                    log("onCallResumeFailed : switching " + mForegroundCall + " with "
1260707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                            + mBackgroundCall);
1261707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                }
1262276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                mForegroundCall.switchWith(mBackgroundCall);
1263276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                mCallExpectedToResume = null;
1264276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn                mSwitchingFgAndBgCalls = false;
1265276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            }
1266276bc50374a46461b334fef28fdf07b536d96c71Tyler Gunn            mPhone.notifySuppServiceFailed(Phone.SuppService.RESUME);
1267a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1268a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1269a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1270a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallResumeReceived(ImsCall imsCall) {
1271a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallResumeReceived");
1272a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1273a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (mOnHoldToneStarted) {
1274a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mPhone.stopOnHoldTone();
1275a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mOnHoldToneStarted = false;
1276a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
127708e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh
127808e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            SuppServiceNotification supp = new SuppServiceNotification();
127908e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            // Type of notification: 0 = MO; 1 = MT
128008e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            // Refer SuppServiceNotification class documentation.
128108e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            supp.notificationType = 1;
128208e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            supp.code = SuppServiceNotification.MT_CODE_CALL_RETRIEVED;
128308e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            mPhone.notifySuppSvcNotification(supp);
1284a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1285a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1286a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1287a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallHoldReceived(ImsCall imsCall) {
1288a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallHoldReceived");
1289a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1290a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ImsPhoneConnection conn = findConnection(imsCall);
1291a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (conn != null && conn.getState() == ImsPhoneCall.State.ACTIVE) {
1292a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (!mOnHoldToneStarted && ImsPhoneCall.isLocalTone(imsCall)) {
1293a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPhone.startOnHoldTone();
1294a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mOnHoldToneStarted = true;
1295a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1296a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
129708e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh
129808e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            SuppServiceNotification supp = new SuppServiceNotification();
129908e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            // Type of notification: 0 = MO; 1 = MT
130008e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            // Refer SuppServiceNotification class documentation.
130108e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            supp.notificationType = 1;
130208e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            supp.code = SuppServiceNotification.MT_CODE_CALL_ON_HOLD;
130308e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            mPhone.notifySuppSvcNotification(supp);
130408e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh        }
130508e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh
130608e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh        @Override
130708e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh        public void onCallSuppServiceReceived(ImsCall call,
130808e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh                ImsSuppServiceNotification suppServiceInfo) {
130908e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            if (DBG) log("onCallSuppServiceReceived: suppServiceInfo=" + suppServiceInfo);
131008e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh
131108e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            SuppServiceNotification supp = new SuppServiceNotification();
13128762e33ba987774e43aa9f4e216ebdb084d3a03eTyler Gunn            supp.notificationType = suppServiceInfo.notificationType;
131308e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            supp.code = suppServiceInfo.code;
131408e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            supp.index = suppServiceInfo.index;
131508e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            supp.number = suppServiceInfo.number;
131608e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            supp.history = suppServiceInfo.history;
131708e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh
131808e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            mPhone.notifySuppSvcNotification(supp);
1319a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1320a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1321a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1322007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam        public void onCallMerged(final ImsCall call, final ImsCall peerCall, boolean swapCalls) {
1323a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onCallMerged");
1324a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1325707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            ImsPhoneCall foregroundImsPhoneCall = findConnection(call).getCall();
1326007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            ImsPhoneConnection peerConnection = findConnection(peerCall);
1327707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            ImsPhoneCall peerImsPhoneCall = peerConnection == null ? null
1328707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                    : peerConnection.getCall();
1329007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam
1330fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn            if (swapCalls) {
1331007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam                switchAfterConferenceSuccess();
1332fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn            }
1333707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            foregroundImsPhoneCall.merge(peerImsPhoneCall, ImsPhoneCall.State.ACTIVE);
1334007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam
1335288268d5528e0df03f348e303954813cb188c55bRekha Kumar            // TODO Temporary code. Remove the try-catch block from the runnable once thread
1336288268d5528e0df03f348e303954813cb188c55bRekha Kumar            // synchronization is fixed.
1337288268d5528e0df03f348e303954813cb188c55bRekha Kumar            Runnable r = new Runnable() {
1338288268d5528e0df03f348e303954813cb188c55bRekha Kumar                @Override
1339288268d5528e0df03f348e303954813cb188c55bRekha Kumar                public void run() {
1340288268d5528e0df03f348e303954813cb188c55bRekha Kumar                    try {
1341288268d5528e0df03f348e303954813cb188c55bRekha Kumar                        final ImsPhoneConnection conn = findConnection(call);
1342288268d5528e0df03f348e303954813cb188c55bRekha Kumar                        log("onCallMerged: ImsPhoneConnection=" + conn);
1343288268d5528e0df03f348e303954813cb188c55bRekha Kumar                        log("onCallMerged: CurrentVideoProvider=" + conn.getVideoProvider());
1344288268d5528e0df03f348e303954813cb188c55bRekha Kumar                        setVideoCallProvider(conn, call);
1345288268d5528e0df03f348e303954813cb188c55bRekha Kumar                        log("onCallMerged: CurrentVideoProvider=" + conn.getVideoProvider());
1346288268d5528e0df03f348e303954813cb188c55bRekha Kumar                    } catch (Exception e) {
1347288268d5528e0df03f348e303954813cb188c55bRekha Kumar                        loge("onCallMerged: exception " + e);
1348288268d5528e0df03f348e303954813cb188c55bRekha Kumar                    }
1349288268d5528e0df03f348e303954813cb188c55bRekha Kumar                }
1350288268d5528e0df03f348e303954813cb188c55bRekha Kumar            };
1351288268d5528e0df03f348e303954813cb188c55bRekha Kumar
1352288268d5528e0df03f348e303954813cb188c55bRekha Kumar            ImsPhoneCallTracker.this.post(r);
1353288268d5528e0df03f348e303954813cb188c55bRekha Kumar
1354007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            // After merge complete, update foreground as Active
1355007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            // and background call as Held, if background call exists
1356007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            processCallStateChange(mForegroundCall.getImsCall(), ImsPhoneCall.State.ACTIVE,
1357007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam                    DisconnectCause.NOT_DISCONNECTED);
1358007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            if (peerConnection != null) {
1359007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam                processCallStateChange(mBackgroundCall.getImsCall(), ImsPhoneCall.State.HOLDING,
1360007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam                    DisconnectCause.NOT_DISCONNECTED);
1361007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            }
1362df0280231c51a24a0b66c24034827d7f73d6e1acSantos Cordon
1363007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            // Check if the merge was requested by an existing conference call. In that
1364007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            // case, no further action is required.
1365007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            if (!call.isMergeRequestedByConf()) {
1366007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam                log("onCallMerged :: calling onMultipartyStateChanged()");
1367007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam                onMultipartyStateChanged(call, true);
1368007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            } else {
1369007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam                log("onCallMerged :: Merge requested by existing conference.");
1370007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam                // Reset the flag.
1371007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam                call.resetIsMergeRequestedByConf(false);
1372007b8ea24251ebb713780be787c069cedb3a4c6aUma Maheswari Ramalingam            }
1373707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            logState();
1374a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1375a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1376a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1377a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallMergeFailed(ImsCall call, ImsReasonInfo reasonInfo) {
13784e47e27d1d2cbd8e533cdd2081c5bc8e51b79ad9Anthony Lee            if (DBG) log("onCallMergeFailed reasonInfo=" + reasonInfo);
137952c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee
138052c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            // TODO: the call to notifySuppServiceFailed throws up the "merge failed" dialog
138152c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            // We should move this into the InCallService so that it is handled appropriately
138252c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            // based on the user facing UI.
1383bd4d6093314c0d2afc4b4f69f352957d01d9bc58Uma Maheswari Ramalingam            mPhone.notifySuppServiceFailed(Phone.SuppService.CONFERENCE);
138452c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee
138552c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            // Start plumbing this even through Telecom so other components can take
138652c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            // appropriate action.
138752c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            ImsPhoneConnection conn = findConnection(call);
138852c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            if (conn != null) {
138952c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee                conn.onConferenceMergeFailed();
139052c1bebcaf545d679923ffbac870eb581faf2b13Anthony Lee            }
1391a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1392fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn
1393fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn        /**
1394f53559f13dc272115f27f3b23955933da45ce127Tyler Gunn         * Called when the state of IMS conference participant(s) has changed.
1395fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn         *
1396fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn         * @param call the call object that carries out the IMS call.
1397f53559f13dc272115f27f3b23955933da45ce127Tyler Gunn         * @param participants the participant(s) and their new state information.
1398fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn         */
1399fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn        @Override
1400f53559f13dc272115f27f3b23955933da45ce127Tyler Gunn        public void onConferenceParticipantsStateChanged(ImsCall call,
1401f53559f13dc272115f27f3b23955933da45ce127Tyler Gunn                List<ConferenceParticipant> participants) {
1402f53559f13dc272115f27f3b23955933da45ce127Tyler Gunn            if (DBG) log("onConferenceParticipantsStateChanged");
1403fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn
1404fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn            ImsPhoneConnection conn = findConnection(call);
1405fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn            if (conn != null) {
1406f53559f13dc272115f27f3b23955933da45ce127Tyler Gunn                conn.updateConferenceParticipants(participants);
1407fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn            }
1408fdca22cc56b0e1ef1504e36a5aacb2ebbc4d146cTyler Gunn        }
14096d91e295add44a5b7e611cb51401a20b3caa6571Pavel Zhamaitsiak
14106d91e295add44a5b7e611cb51401a20b3caa6571Pavel Zhamaitsiak        @Override
14116d91e295add44a5b7e611cb51401a20b3caa6571Pavel Zhamaitsiak        public void onCallSessionTtyModeReceived(ImsCall call, int mode) {
14126d91e295add44a5b7e611cb51401a20b3caa6571Pavel Zhamaitsiak            mPhone.onTtyModeReceived(mode);
14136d91e295add44a5b7e611cb51401a20b3caa6571Pavel Zhamaitsiak        }
14140ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar
14150ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        @Override
14160ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        public void onCallHandover(ImsCall imsCall, int srcAccessTech, int targetAccessTech,
14170ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            ImsReasonInfo reasonInfo) {
14180ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            if (DBG) {
14190ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar                log("onCallHandover ::  srcAccessTech=" + srcAccessTech + ", targetAccessTech=" +
14200ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar                    targetAccessTech + ", reasonInfo=" + reasonInfo);
14210ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            }
14220ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        }
14230ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar
14240ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        @Override
14250ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        public void onCallHandoverFailed(ImsCall imsCall, int srcAccessTech, int targetAccessTech,
14260ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            ImsReasonInfo reasonInfo) {
14270ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            if (DBG) {
14280ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar                log("onCallHandoverFailed :: srcAccessTech=" + srcAccessTech +
14290ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar                    ", targetAccessTech=" + targetAccessTech + ", reasonInfo=" + reasonInfo);
14300ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            }
14310ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        }
1432ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn
1433ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn        /**
1434ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn         * Handles a change to the multiparty state for an {@code ImsCall}.  Notifies the associated
1435ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn         * {@link ImsPhoneConnection} of the change.
1436ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn         *
1437ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn         * @param imsCall The IMS call.
1438ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn         * @param isMultiParty {@code true} if the call became multiparty, {@code false}
1439ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn         *      otherwise.
1440ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn         */
1441ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn        @Override
1442ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn        public void onMultipartyStateChanged(ImsCall imsCall, boolean isMultiParty) {
1443ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn            if (DBG) log("onMultipartyStateChanged to " + (isMultiParty ? "Y" : "N"));
1444ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn
1445ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn            ImsPhoneConnection conn = findConnection(imsCall);
1446ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn            if (conn != null) {
1447ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn                conn.updateMultipartyState(isMultiParty);
1448ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn            }
1449ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn        }
1450a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    };
1451a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1452a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
1453a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * Listen to the IMS call state change
1454a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
1455a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ImsCall.Listener mImsUssdListener = new ImsCall.Listener() {
1456a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1457a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallStarted(ImsCall imsCall) {
1458a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("mImsUssdListener onCallStarted");
1459a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1460a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (imsCall == mUssdSession) {
1461a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mPendingUssd != null) {
1462a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    AsyncResult.forMessage(mPendingUssd);
1463a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingUssd.sendToTarget();
1464a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingUssd = null;
1465a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1466a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1467a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1468a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1469a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1470a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallStartFailed(ImsCall imsCall, ImsReasonInfo reasonInfo) {
1471a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("mImsUssdListener onCallStartFailed reasonCode=" + reasonInfo.getCode());
1472a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1473a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            onCallTerminated(imsCall, reasonInfo);
1474a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1475a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1476a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1477a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallTerminated(ImsCall imsCall, ImsReasonInfo reasonInfo) {
1478a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("mImsUssdListener onCallTerminated reasonCode=" + reasonInfo.getCode());
1479a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1480a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (imsCall == mUssdSession) {
1481a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mUssdSession = null;
1482a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mPendingUssd != null) {
1483a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    CommandException ex =
1484a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                            new CommandException(CommandException.Error.GENERIC_FAILURE);
1485a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    AsyncResult.forMessage(mPendingUssd, null, ex);
1486a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingUssd.sendToTarget();
1487a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingUssd = null;
1488a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1489a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1490a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            imsCall.close();
1491a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1492a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1493a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1494a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onCallUssdMessageReceived(ImsCall call,
1495a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                int mode, String ussdMessage) {
1496a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("mImsUssdListener onCallUssdMessageReceived mode=" + mode);
1497a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1498a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            int ussdMode = -1;
1499a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1500a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            switch(mode) {
1501a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                case ImsCall.USSD_MODE_REQUEST:
1502a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    ussdMode = CommandsInterface.USSD_MODE_REQUEST;
1503a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    break;
1504a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1505a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                case ImsCall.USSD_MODE_NOTIFY:
1506a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    ussdMode = CommandsInterface.USSD_MODE_NOTIFY;
1507a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    break;
1508a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
1509a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1510a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.onIncomingUSSD(ussdMode, ussdMessage);
1511a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1512a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    };
1513a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1514a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
1515a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * Listen to the IMS service state change
1516a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     *
1517a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
1518a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private ImsConnectionStateListener mImsConnectionStateListener =
1519a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        new ImsConnectionStateListener() {
1520a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1521a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onImsConnected() {
1522a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onImsConnected");
1523a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.setServiceState(ServiceState.STATE_IN_SERVICE);
1524bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com            mPhone.setImsRegistered(true);
1525a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1526a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1527a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
15280ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        public void onImsDisconnected(ImsReasonInfo imsReasonInfo) {
15290ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            if (DBG) log("onImsDisconnected imsReasonInfo=" + imsReasonInfo);
1530a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
1531bd4bb4f2250463ba59dc98be649f6aa4df9fb682Libin.Tang@motorola.com            mPhone.setImsRegistered(false);
153253f2bb9ba3118ff4c22e20ab3ad46ec97a72ac24Pavel Zhamaitsiak            mPhone.processDisconnectReason(imsReasonInfo);
1533a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1534a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1535a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
15360ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        public void onImsProgressing() {
15370ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar            if (DBG) log("onImsProgressing");
153808e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
153908e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh            mPhone.setImsRegistered(false);
15400ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        }
15410ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar
15420ba5c4a978fba0c15c8539c790a3ae1793bd99e3Rekha Kumar        @Override
1543a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onImsResumed() {
1544a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onImsResumed");
1545a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.setServiceState(ServiceState.STATE_IN_SERVICE);
1546a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1547a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1548a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        @Override
1549a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        public void onImsSuspended() {
1550a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (DBG) log("onImsSuspended");
1551a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mPhone.setServiceState(ServiceState.STATE_OUT_OF_SERVICE);
1552a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1553cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com
1554cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com        @Override
1555cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com        public void onFeatureCapabilityChanged(int serviceClass,
1556cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com                int[] enabledFeatures, int[] disabledFeatures) {
1557cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com            if (serviceClass == ImsServiceClass.MMTEL) {
1558288268d5528e0df03f348e303954813cb188c55bRekha Kumar                boolean tmpIsVideoCallEnabled = isVideoCallEnabled();
155904b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                // Check enabledFeatures to determine capabilities. We ignore disabledFeatures.
156062a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com                for (int  i = ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE;
1561164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati                        i <= ImsConfig.FeatureConstants.FEATURE_TYPE_UT_OVER_WIFI; i++) {
156262a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com                    if (enabledFeatures[i] == i) {
156304b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                        // If the feature is set to its own integer value it is enabled.
1564915b8a421c34b0872c96199d4390a70d5a76ed98Nathan Harold                        if (DBG) log("onFeatureCapabilityChanged(" + i + ", " + mImsFeatureStrings[i] + "): value=true");
156562a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com                        mImsFeatureEnabled[i] = true;
156604b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                    } else if (enabledFeatures[i]
156704b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                            == ImsConfig.FeatureConstants.FEATURE_TYPE_UNKNOWN) {
156804b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                        // FEATURE_TYPE_UNKNOWN indicates that a feature is disabled.
1569915b8a421c34b0872c96199d4390a70d5a76ed98Nathan Harold                        if (DBG) log("onFeatureCapabilityChanged(" + i + ", " + mImsFeatureStrings[i] + "): value=false");
157062a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com                        mImsFeatureEnabled[i] = false;
157104b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                    } else {
157204b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                        // Feature has unknown state; it is not its own value or -1.
157304b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                        if (DBG) {
1574915b8a421c34b0872c96199d4390a70d5a76ed98Nathan Harold                            loge("onFeatureCapabilityChanged(" + i + ", " +mImsFeatureStrings[i] + "): unexpectedValue="
157504b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                                + enabledFeatures[i]);
157604b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                        }
157762a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com                    }
1578cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com                }
1579288268d5528e0df03f348e303954813cb188c55bRekha Kumar                if (tmpIsVideoCallEnabled != isVideoCallEnabled()) {
1580288268d5528e0df03f348e303954813cb188c55bRekha Kumar                    mPhone.notifyForVideoCapabilityChanged(isVideoCallEnabled());
1581288268d5528e0df03f348e303954813cb188c55bRekha Kumar                }
158204b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee
158304b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                // TODO: Use the ImsCallSession or ImsCallProfile to tell the initial Wifi state and
158404b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                // {@link ImsCallSession.Listener#callSessionHandover} to listen for changes to
158504b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                // wifi capability caused by a handover.
1586164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati                if (DBG) log("onFeatureCapabilityChanged: isVolteEnabled=" + isVolteEnabled()
1587164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati                            + ", isVideoCallEnabled=" + isVideoCallEnabled()
1588164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati                            + ", isVowifiEnabled=" + isVowifiEnabled()
1589164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati                            + ", isUtEnabled=" + isUtEnabled());
159004b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                for (ImsPhoneConnection connection : mConnections) {
159104b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                    connection.updateWifiState();
159204b0216a5f64b70ec4b06f129946fff4ef359878Andrew Lee                }
1593e51d918511afab905399d9fda7f51442f15bd8a7Pavel Zhamaitsiak
1594e51d918511afab905399d9fda7f51442f15bd8a7Pavel Zhamaitsiak                mPhone.onFeatureCapabilityChanged();
1595cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com            }
1596cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com        }
159703545e6c17da992dc0087fcd0db1262277e8da37Omkar Kolangade
159803545e6c17da992dc0087fcd0db1262277e8da37Omkar Kolangade        @Override
159903545e6c17da992dc0087fcd0db1262277e8da37Omkar Kolangade        public void onVoiceMessageCountChanged(int count) {
160003545e6c17da992dc0087fcd0db1262277e8da37Omkar Kolangade            if (DBG) log("onVoiceMessageCountChanged :: count=" + count);
160103545e6c17da992dc0087fcd0db1262277e8da37Omkar Kolangade            mPhone.mDefaultPhone.setVoiceMessageCount(count);
160203545e6c17da992dc0087fcd0db1262277e8da37Omkar Kolangade        }
1603a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    };
1604a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1605a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /* package */
1606a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    ImsUtInterface getUtInterface() throws ImsException {
1607a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mImsManager == null) {
1608a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            throw new ImsException("no ims manager", ImsReasonInfo.CODE_UNSPECIFIED);
1609a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1610a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1611a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsUtInterface ut = mImsManager.getSupplementaryServiceConfiguration(mServiceId);
1612a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return ut;
1613a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1614a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
16154be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam    private void transferHandoverConnections(ImsPhoneCall call) {
16164be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        if (call.mConnections != null) {
16174be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            for (Connection c : call.mConnections) {
16184be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                c.mPreHandoverState = call.mState;
16194be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                log ("Connection state before handover is " + c.getStateBeforeHandover());
16204be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            }
16214be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        }
16224be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        if (mHandoverCall.mConnections == null ) {
16234be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            mHandoverCall.mConnections = call.mConnections;
16244be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        } else { // Multi-call SRVCC
16254be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            mHandoverCall.mConnections.addAll(call.mConnections);
16264be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        }
16274be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        if (mHandoverCall.mConnections != null) {
16284be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            if (call.getImsCall() != null) {
16294be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                call.getImsCall().close();
16304be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            }
16314be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            for (Connection c : mHandoverCall.mConnections) {
16324be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam                ((ImsPhoneConnection)c).changeParent(mHandoverCall);
163352c193f0c615a9153a702ea2597217202613e413Libin.Tang@motorola.com                ((ImsPhoneConnection)c).releaseWakeLock();
16344be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            }
16354be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        }
16364be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        if (call.getState().isAlive()) {
16374be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            log ("Call is alive and state is " + call.mState);
16384be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            mHandoverCall.mState = call.mState;
16394be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        }
16404be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        call.mConnections.clear();
16414be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam        call.mState = ImsPhoneCall.State.IDLE;
16424be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam    }
16434be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam
1644a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /* package */
1645a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void notifySrvccState(Call.SrvccState state) {
1646a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("notifySrvccState state=" + state);
1647a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1648a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mSrvccState = state;
1649a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1650a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mSrvccState == Call.SrvccState.COMPLETED) {
16514be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            transferHandoverConnections(mForegroundCall);
16524be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            transferHandoverConnections(mBackgroundCall);
16534be56374921b52d54b80889540d982f39d26e3abUma Maheswari Ramalingam            transferHandoverConnections(mRingingCall);
1654a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1655a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1656a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1657a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //****** Overridden from Handler
1658a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1659a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
1660a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void
1661a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    handleMessage (Message msg) {
1662a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        AsyncResult ar;
1663a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (DBG) log("handleMessage what=" + msg.what);
1664a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1665a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        switch (msg.what) {
1666a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case EVENT_HANGUP_PENDINGMO:
1667a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mPendingMO != null) {
1668a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingMO.onDisconnect();
1669a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    removeConnection(mPendingMO);
1670a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    mPendingMO = null;
1671a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1672c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn                mPendingIntentExtras = null;
1673a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                updatePhoneState();
1674a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mPhone.notifyPreciseCallStateChanged();
1675a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
1676a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case EVENT_RESUME_BACKGROUND:
1677a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                try {
1678a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    resumeWaitingOrHolding();
1679a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                } catch (CallStateException e) {
1680a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    if (Phone.DEBUG_PHONE) {
1681a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                        loge("handleMessage EVENT_RESUME_BACKGROUND exception=" + e);
1682a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    }
1683a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
1684a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
1685a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            case EVENT_DIAL_PENDINGMO:
1686c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn                dialInternal(mPendingMO, mClirMode, mPendingCallVideoState, mPendingIntentExtras);
1687c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn                mPendingIntentExtras = null;
1688a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                break;
168904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
169004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            case EVENT_EXIT_ECM_RESPONSE_CDMA:
169104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                // no matter the result, we still do the same here
169204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                if (pendingCallInEcm) {
1693288268d5528e0df03f348e303954813cb188c55bRekha Kumar                    dialInternal(mPendingMO, pendingCallClirMode,
1694c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn                            mPendingCallVideoState, mPendingIntentExtras);
1695c1d9e728264af06808d4374d39c71dd81642cafcTyler Gunn                    mPendingIntentExtras = null;
169604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                    pendingCallInEcm = false;
169704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                }
169804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                mPhone.unsetOnEcbModeExitResponse(this);
169904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam                break;
1700a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
1701a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1702a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1703a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
1704a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void log(String msg) {
1705a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.d(LOG_TAG, "[ImsPhoneCallTracker] " + msg);
1706a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1707a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1708a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void loge(String msg) {
1709a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        Rlog.e(LOG_TAG, "[ImsPhoneCallTracker] " + msg);
1710a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1711a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1712707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    /**
1713707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn     * Logs the current state of the ImsPhoneCallTracker.  Useful for debugging issues with
1714707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn     * call tracking.
1715707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn     */
1716707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    /* package */
1717707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    void logState() {
1718707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        if (!VERBOSE_STATE_LOGGING) {
1719707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            return;
1720707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        }
1721707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn
1722707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        StringBuilder sb = new StringBuilder();
1723707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append("Current IMS PhoneCall State:\n");
1724707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append(" Foreground: ");
1725707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append(mForegroundCall);
1726707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append("\n");
1727707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append(" Background: ");
1728707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append(mBackgroundCall);
1729707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append("\n");
1730707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append(" Ringing: ");
1731707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append(mRingingCall);
1732707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append("\n");
1733707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append(" Handover: ");
1734707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append(mHandoverCall);
1735707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append("\n");
1736707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        Rlog.v(LOG_TAG, sb.toString());
1737707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    }
1738707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn
1739a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
1740a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1741a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println("ImsPhoneCallTracker extends:");
1742a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        super.dump(fd, pw, args);
1743a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mVoiceCallEndedRegistrants=" + mVoiceCallEndedRegistrants);
1744a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mVoiceCallStartedRegistrants=" + mVoiceCallStartedRegistrants);
1745a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mRingingCall=" + mRingingCall);
1746a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mForegroundCall=" + mForegroundCall);
1747a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mBackgroundCall=" + mBackgroundCall);
1748a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mHandoverCall=" + mHandoverCall);
1749a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mPendingMO=" + mPendingMO);
1750a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        //pw.println(" mHangupPendingMO=" + mHangupPendingMO);
1751a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mPhone=" + mPhone);
1752a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mDesiredMute=" + mDesiredMute);
1753a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        pw.println(" mState=" + mState);
1754a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
1755a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
1756a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
1757a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    protected void handlePollCalls(AsyncResult ar) {
1758a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
175904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
176004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    /* package */
176104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    ImsEcbm getEcbmInterface() throws ImsException {
176204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        if (mImsManager == null) {
176304e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam            throw new ImsException("no ims manager", ImsReasonInfo.CODE_UNSPECIFIED);
176404e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        }
176504e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
176604e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        ImsEcbm ecbm = mImsManager.getEcbmInterface(mServiceId);
176704e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        return ecbm;
176804e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    }
176904e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam
177004e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    public boolean isInEmergencyCall() {
177104e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam        return mIsInEmergencyCall;
177204e36a78936967df68d9175ac09dd3f087727888Uma Maheswari Ramalingam    }
1773cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com
1774cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com    public boolean isVolteEnabled() {
177562a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com        return mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE];
177662a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com    }
177762a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com
177862a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com    public boolean isVowifiEnabled() {
177962a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com        return mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI];
1780cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com    }
1781cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com
1782288268d5528e0df03f348e303954813cb188c55bRekha Kumar    public boolean isVideoCallEnabled() {
178362a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com        return (mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE]
178462a2b2f341be6130e4022b487648ff2fee06db8cLibin.Tang@motorola.com                || mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_WIFI]);
1785cf91ae7acc62eba22d9e652e5de5fb90a89e2ac8Libin.Tang@motorola.com    }
1786288268d5528e0df03f348e303954813cb188c55bRekha Kumar
1787b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com    @Override
1788b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com    public PhoneConstants.State getState() {
1789b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com        return mState;
1790b79f845a0451895b0f0b8a926a8571511d476ce8Libin.Tang@motorola.com    }
1791288268d5528e0df03f348e303954813cb188c55bRekha Kumar
1792288268d5528e0df03f348e303954813cb188c55bRekha Kumar    private void setVideoCallProvider(ImsPhoneConnection conn, ImsCall imsCall)
1793288268d5528e0df03f348e303954813cb188c55bRekha Kumar            throws RemoteException {
1794288268d5528e0df03f348e303954813cb188c55bRekha Kumar        IImsVideoCallProvider imsVideoCallProvider =
1795288268d5528e0df03f348e303954813cb188c55bRekha Kumar                imsCall.getCallSession().getVideoCallProvider();
1796288268d5528e0df03f348e303954813cb188c55bRekha Kumar        if (imsVideoCallProvider != null) {
1797288268d5528e0df03f348e303954813cb188c55bRekha Kumar            ImsVideoCallProviderWrapper imsVideoCallProviderWrapper =
1798288268d5528e0df03f348e303954813cb188c55bRekha Kumar                    new ImsVideoCallProviderWrapper(imsVideoCallProvider);
1799288268d5528e0df03f348e303954813cb188c55bRekha Kumar            conn.setVideoProvider(imsVideoCallProviderWrapper);
1800288268d5528e0df03f348e303954813cb188c55bRekha Kumar        }
1801288268d5528e0df03f348e303954813cb188c55bRekha Kumar    }
1802164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati
1803164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati    public boolean isUtEnabled() {
1804164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati        return (mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_UT_OVER_LTE]
1805164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati            || mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_UT_OVER_WIFI]);
1806164cea0175c29fa2da4652253b1f3b3c03707c3eAnju Mathapati    }
1807a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville}
1808