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 19a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.content.Context; 20d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunnimport android.net.Uri; 21a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.AsyncResult; 2208e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganeshimport android.os.Bundle; 23a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Handler; 24a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Looper; 25a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Message; 268a5c54f8ba1793a89bb8e18e819d1fc5b85bc1bfBrad Ebingerimport android.os.Messenger; 276bb557b243f3fc9984b82319026519608ada2c9cRoshan Piusimport android.os.PersistableBundle; 28a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.PowerManager; 29a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.Registrant; 30a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.os.SystemClock; 31db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunnimport android.telecom.VideoProfile; 326bb557b243f3fc9984b82319026519608ada2c9cRoshan Piusimport android.telephony.CarrierConfigManager; 33a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.DisconnectCause; 34a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.PhoneNumberUtils; 35a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.Rlog; 362e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunnimport android.telephony.ServiceState; 37baece8c63121b5e3660ecc716bcff87f73f791ffHall Liuimport android.telephony.ims.ImsCallProfile; 38baece8c63121b5e3660ecc716bcff87f73f791ffHall Liuimport android.telephony.ims.ImsStreamMediaProfile; 39eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganeshimport android.text.TextUtils; 40a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 41286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunnimport com.android.ims.ImsCall; 422999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunnimport com.android.ims.ImsException; 43db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunnimport com.android.ims.internal.ImsVideoCallProviderWrapper; 44a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.CallStateException; 45a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.Connection; 46a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.Phone; 47a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.PhoneConstants; 48a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.UUSInfo; 49a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 5021048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkarimport java.util.Objects; 5121048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar 52a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville/** 53a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * {@hide} 54a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville */ 55db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunnpublic class ImsPhoneConnection extends Connection implements 56db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn ImsVideoCallProviderWrapper.ImsVideoProviderWrapperCallback { 57db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn 58a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private static final String LOG_TAG = "ImsPhoneConnection"; 59a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private static final boolean DBG = true; 60a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 61a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville //***** Instance Variables 62a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 63a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private ImsPhoneCallTracker mOwner; 64a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private ImsPhoneCall mParent; 65a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private ImsCall mImsCall; 6621048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar private Bundle mExtras = new Bundle(); 67a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 68a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private boolean mDisconnected; 69a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 70a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville /* 71a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville int mIndex; // index in ImsPhoneCallTracker.connections[], -1 if unassigned 72a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // The GSM index is 1 + this 73a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville */ 74a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 75a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville /* 76a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * These time/timespan values are based on System.currentTimeMillis(), 77a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * i.e., "wall clock" time. 78a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville */ 79a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private long mDisconnectTime; 80a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 81a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private UUSInfo mUusInfo; 82a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private Handler mHandler; 838a5c54f8ba1793a89bb8e18e819d1fc5b85bc1bfBrad Ebinger private Messenger mHandlerMessenger; 84a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 85a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private PowerManager.WakeLock mPartialWakeLock; 86a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 87fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn // The cached connect time of the connection when it turns into a conference. 88fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn private long mConferenceConnectTime = 0; 89fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn 906bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius // The cached delay to be used between DTMF tones fetched from carrier config. 916bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius private int mDtmfToneDelay = 0; 926bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius 938bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan private boolean mIsEmergency = false; 948bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan 952e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn /** 96db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn * Used to indicate that video state changes detected by 97db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn * {@link #updateMediaCapabilities(ImsCall)} should be ignored. When a video state change from 98db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn * unpaused to paused occurs, we set this flag and then update the existing video state when 99db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn * new {@link #onReceiveSessionModifyResponse(int, VideoProfile, VideoProfile)} callbacks come 100db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn * in. When the video un-pauses we continue receiving the video state updates. 101db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn */ 102db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn private boolean mShouldIgnoreVideoStateChanges = false; 103db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn 104359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn private ImsVideoCallProviderWrapper mImsVideoCallProviderWrapper; 105359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn 106222bd9d64068a23f5470561655ca4dbd2359eeceJayachandran C private int mPreciseDisconnectCause = 0; 107222bd9d64068a23f5470561655ca4dbd2359eeceJayachandran C 108fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu private ImsRttTextHandler mRttTextHandler; 109fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu private android.telecom.Connection.RttTextStream mRttTextStream; 1103d28f89927137ce03128a0244a698ca5162e8165Hall Liu // This reflects the RTT status as reported to us by the IMS stack via the media profile. 1113d28f89927137ce03128a0244a698ca5162e8165Hall Liu private boolean mIsRttEnabledForCall = false; 112fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu 113286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn /** 114286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn * Used to indicate that this call is in the midst of being merged into a conference. 115286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn */ 116286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn private boolean mIsMergeInProcess = false; 117286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn 11863fa599fef0383b41f85e1fc3a38d33c4434e24aTyler Gunn /** 1197a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn * Used as an override to determine whether video is locally available for this call. 1207a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn * This allows video availability to be overridden in the case that the modem says video is 1217a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn * currently available, but mobile data is off and the carrier is metering data for video 1227a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn * calls. 1237a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn */ 1247a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn private boolean mIsVideoEnabled = true; 1257a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn 126a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville //***** Event Constants 127a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private static final int EVENT_DTMF_DONE = 1; 128a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private static final int EVENT_PAUSE_DONE = 2; 129a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private static final int EVENT_NEXT_POST_DIAL = 3; 130a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private static final int EVENT_WAKE_LOCK_TIMEOUT = 4; 1316bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius private static final int EVENT_DTMF_DELAY_DONE = 5; 132a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 133a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville //***** Constants 134a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private static final int PAUSE_DELAY_MILLIS = 3 * 1000; 135a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private static final int WAKE_LOCK_TIMEOUT_MILLIS = 60*1000; 136a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 137a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville //***** Inner Classes 138a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 139a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville class MyHandler extends Handler { 140a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville MyHandler(Looper l) {super(l);} 141a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 142a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville @Override 143a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public void 144a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville handleMessage(Message msg) { 145a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 146a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville switch (msg.what) { 147a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville case EVENT_NEXT_POST_DIAL: 1486bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius case EVENT_DTMF_DELAY_DONE: 149a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville case EVENT_PAUSE_DONE: 150a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville processNextPostDialChar(); 151a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville break; 152a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville case EVENT_WAKE_LOCK_TIMEOUT: 153a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville releaseWakeLock(); 154a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville break; 1556bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius case EVENT_DTMF_DONE: 1566bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius // We may need to add a delay specified by carrier between DTMF tones that are 1576bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius // sent out. 1586bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_DTMF_DELAY_DONE), 1596bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius mDtmfToneDelay); 1606bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius break; 161a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 162a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 163a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 164a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 165a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville //***** Constructors 166a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 167a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville /** This is probably an MT call */ 168f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxu public ImsPhoneConnection(Phone phone, ImsCall imsCall, ImsPhoneCallTracker ct, 16908e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh ImsPhoneCall parent, boolean isUnknown) { 170c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajan super(PhoneConstants.PHONE_TYPE_IMS); 1716bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius createWakeLock(phone.getContext()); 172a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville acquireWakeLock(); 173a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 174a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mOwner = ct; 175a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mHandler = new MyHandler(mOwner.getLooper()); 1768a5c54f8ba1793a89bb8e18e819d1fc5b85bc1bfBrad Ebinger mHandlerMessenger = new Messenger(mHandler); 177a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mImsCall = imsCall; 178a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 179a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if ((imsCall != null) && (imsCall.getCallProfile() != null)) { 180a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mAddress = imsCall.getCallProfile().getCallExtra(ImsCallProfile.EXTRA_OI); 181a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mCnapName = imsCall.getCallProfile().getCallExtra(ImsCallProfile.EXTRA_CNA); 182d325833e9248c05305b1edabb1d8efc827803f75Jing Zhao mNumberPresentation = ImsCallProfile.OIRToPresentation( 183a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville imsCall.getCallProfile().getCallExtraInt(ImsCallProfile.EXTRA_OIR)); 184d325833e9248c05305b1edabb1d8efc827803f75Jing Zhao mCnapNamePresentation = ImsCallProfile.OIRToPresentation( 185a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville imsCall.getCallProfile().getCallExtraInt(ImsCallProfile.EXTRA_CNAP)); 1866a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee updateMediaCapabilities(imsCall); 187a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else { 188a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mNumberPresentation = PhoneConstants.PRESENTATION_UNKNOWN; 189a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mCnapNamePresentation = PhoneConstants.PRESENTATION_UNKNOWN; 190a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 191a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 19208e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh mIsIncoming = !isUnknown; 193a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mCreateTime = System.currentTimeMillis(); 194a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mUusInfo = null; 195a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 196553db651cd5a51eedde0259d5a25e91700ef96c5Tyler Gunn // Ensure any extras set on the ImsCallProfile at the start of the call are cached locally 197553db651cd5a51eedde0259d5a25e91700ef96c5Tyler Gunn // in the ImsPhoneConnection. This isn't going to inform any listeners (since the original 198553db651cd5a51eedde0259d5a25e91700ef96c5Tyler Gunn // connection is not likely to be associated with a TelephonyConnection yet). 199553db651cd5a51eedde0259d5a25e91700ef96c5Tyler Gunn updateExtras(imsCall); 200553db651cd5a51eedde0259d5a25e91700ef96c5Tyler Gunn 201a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mParent = parent; 20208e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh mParent.attach(this, 20308e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh (mIsIncoming? ImsPhoneCall.State.INCOMING: ImsPhoneCall.State.DIALING)); 2046bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius 2056bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius fetchDtmfToneDelay(phone); 206c6e763fa8aa1121f9c5aef16368115b06e31c6a2Jimmy Wu 207c6e763fa8aa1121f9c5aef16368115b06e31c6a2Jimmy Wu if (phone.getContext().getResources().getBoolean( 208c6e763fa8aa1121f9c5aef16368115b06e31c6a2Jimmy Wu com.android.internal.R.bool.config_use_voip_mode_for_ims)) { 209c6e763fa8aa1121f9c5aef16368115b06e31c6a2Jimmy Wu setAudioModeIsVoip(true); 210c6e763fa8aa1121f9c5aef16368115b06e31c6a2Jimmy Wu } 211a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 212a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 213a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville /** This is an MO call, created when dialing */ 214f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxu public ImsPhoneConnection(Phone phone, String dialString, ImsPhoneCallTracker ct, 2158bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan ImsPhoneCall parent, boolean isEmergency) { 216c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajan super(PhoneConstants.PHONE_TYPE_IMS); 2176bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius createWakeLock(phone.getContext()); 218a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville acquireWakeLock(); 219a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 220a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mOwner = ct; 221a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mHandler = new MyHandler(mOwner.getLooper()); 222a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 223a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mDialString = dialString; 224a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 225a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mAddress = PhoneNumberUtils.extractNetworkPortionAlt(dialString); 226a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mPostDialString = PhoneNumberUtils.extractPostDialPortion(dialString); 227a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 228a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville //mIndex = -1; 229a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 230a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mIsIncoming = false; 231a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mCnapName = null; 232a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mCnapNamePresentation = PhoneConstants.PRESENTATION_ALLOWED; 233a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mNumberPresentation = PhoneConstants.PRESENTATION_ALLOWED; 234a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mCreateTime = System.currentTimeMillis(); 235a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 236a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mParent = parent; 237a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville parent.attachFake(this, ImsPhoneCall.State.DIALING); 2386bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius 2398bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan mIsEmergency = isEmergency; 2408bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan 2416bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius fetchDtmfToneDelay(phone); 242c6e763fa8aa1121f9c5aef16368115b06e31c6a2Jimmy Wu 243c6e763fa8aa1121f9c5aef16368115b06e31c6a2Jimmy Wu if (phone.getContext().getResources().getBoolean( 244c6e763fa8aa1121f9c5aef16368115b06e31c6a2Jimmy Wu com.android.internal.R.bool.config_use_voip_mode_for_ims)) { 245c6e763fa8aa1121f9c5aef16368115b06e31c6a2Jimmy Wu setAudioModeIsVoip(true); 246c6e763fa8aa1121f9c5aef16368115b06e31c6a2Jimmy Wu } 247a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 248a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 249a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public void dispose() { 250a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 251a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 252a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville static boolean 253a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville equalsHandlesNulls (Object a, Object b) { 254a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return (a == null) ? (b == null) : a.equals (b); 255a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 256a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 25774c8509aede6fe748904e75c156049b4f1ba5e28Hanada Masafumi static boolean 25874c8509aede6fe748904e75c156049b4f1ba5e28Hanada Masafumi equalsBaseDialString (String a, String b) { 25974c8509aede6fe748904e75c156049b4f1ba5e28Hanada Masafumi return (a == null) ? (b == null) : (b != null && a.startsWith (b)); 26074c8509aede6fe748904e75c156049b4f1ba5e28Hanada Masafumi } 26174c8509aede6fe748904e75c156049b4f1ba5e28Hanada Masafumi 2627a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn private int applyLocalCallCapabilities(ImsCallProfile localProfile, int capabilities) { 2637a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn Rlog.i(LOG_TAG, "applyLocalCallCapabilities - localProfile = " + localProfile); 264f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn capabilities = removeCapability(capabilities, 2652e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn Connection.Capability.SUPPORTS_VT_LOCAL_BIDIRECTIONAL); 266f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn 2677a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn if (!mIsVideoEnabled) { 2687a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn Rlog.i(LOG_TAG, "applyLocalCallCapabilities - disabling video (overidden)"); 2697a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn return capabilities; 2707a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn } 271f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn switch (localProfile.mCallType) { 272f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn case ImsCallProfile.CALL_TYPE_VT: 2732e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn // Fall-through 274f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn case ImsCallProfile.CALL_TYPE_VIDEO_N_VOICE: 275f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn capabilities = addCapability(capabilities, 2762e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn Connection.Capability.SUPPORTS_VT_LOCAL_BIDIRECTIONAL); 277f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn break; 278f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn } 279f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn return capabilities; 280f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn } 281f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn 282f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn private static int applyRemoteCallCapabilities(ImsCallProfile remoteProfile, int capabilities) { 2832e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn Rlog.w(LOG_TAG, "applyRemoteCallCapabilities - remoteProfile = "+remoteProfile); 284f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn capabilities = removeCapability(capabilities, 2852e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn Connection.Capability.SUPPORTS_VT_REMOTE_BIDIRECTIONAL); 286f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn 287f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn switch (remoteProfile.mCallType) { 288f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn case ImsCallProfile.CALL_TYPE_VT: 2892e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn // fall-through 290f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn case ImsCallProfile.CALL_TYPE_VIDEO_N_VOICE: 291f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn capabilities = addCapability(capabilities, 2922e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn Connection.Capability.SUPPORTS_VT_REMOTE_BIDIRECTIONAL); 293f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn break; 294f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn } 295f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn return capabilities; 296f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn } 297f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn 298a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville @Override 299a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public String getOrigDialString(){ 300a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return mDialString; 301a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 302a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 303a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville @Override 304a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public ImsPhoneCall getCall() { 305a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return mParent; 306a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 307a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 308a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville @Override 309a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public long getDisconnectTime() { 310a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return mDisconnectTime; 311a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 312a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 313a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville @Override 314a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public long getHoldingStartTime() { 315a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return mHoldingStartTime; 316a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 317a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 318a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville @Override 319a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public long getHoldDurationMillis() { 320a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (getState() != ImsPhoneCall.State.HOLDING) { 321a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // If not holding, return 0 322a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return 0; 323a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else { 324a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return SystemClock.elapsedRealtime() - mHoldingStartTime; 325a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 326a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 327a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 328a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public void setDisconnectCause(int cause) { 329a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mCause = cause; 330a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 331a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 33233cfb500a7cf192adfc5ca06792fe3847073b6c1Chao Liu @Override 33333cfb500a7cf192adfc5ca06792fe3847073b6c1Chao Liu public String getVendorDisconnectCause() { 33433cfb500a7cf192adfc5ca06792fe3847073b6c1Chao Liu return null; 33533cfb500a7cf192adfc5ca06792fe3847073b6c1Chao Liu } 33633cfb500a7cf192adfc5ca06792fe3847073b6c1Chao Liu 337a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public ImsPhoneCallTracker getOwner () { 338a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return mOwner; 339a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 340a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 341a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville @Override 342a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public ImsPhoneCall.State getState() { 343a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (mDisconnected) { 344a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return ImsPhoneCall.State.DISCONNECTED; 345a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else { 346a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return super.getState(); 347a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 348a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 349a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 350a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville @Override 3514611e65ec532915b3a6968459d68e5a2dc3a08c8Pooja Jain public void deflect(String number) throws CallStateException { 3524611e65ec532915b3a6968459d68e5a2dc3a08c8Pooja Jain if (mParent.getState().isRinging()) { 3534611e65ec532915b3a6968459d68e5a2dc3a08c8Pooja Jain try { 3544611e65ec532915b3a6968459d68e5a2dc3a08c8Pooja Jain if (mImsCall != null) { 3554611e65ec532915b3a6968459d68e5a2dc3a08c8Pooja Jain mImsCall.deflect(number); 3564611e65ec532915b3a6968459d68e5a2dc3a08c8Pooja Jain } else { 3574611e65ec532915b3a6968459d68e5a2dc3a08c8Pooja Jain throw new CallStateException("no valid ims call to deflect"); 3584611e65ec532915b3a6968459d68e5a2dc3a08c8Pooja Jain } 3594611e65ec532915b3a6968459d68e5a2dc3a08c8Pooja Jain } catch (ImsException e) { 3604611e65ec532915b3a6968459d68e5a2dc3a08c8Pooja Jain throw new CallStateException("cannot deflect call"); 3614611e65ec532915b3a6968459d68e5a2dc3a08c8Pooja Jain } 3624611e65ec532915b3a6968459d68e5a2dc3a08c8Pooja Jain } else { 3634611e65ec532915b3a6968459d68e5a2dc3a08c8Pooja Jain throw new CallStateException("phone not ringing"); 3644611e65ec532915b3a6968459d68e5a2dc3a08c8Pooja Jain } 3654611e65ec532915b3a6968459d68e5a2dc3a08c8Pooja Jain } 3664611e65ec532915b3a6968459d68e5a2dc3a08c8Pooja Jain 3674611e65ec532915b3a6968459d68e5a2dc3a08c8Pooja Jain @Override 368a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public void hangup() throws CallStateException { 369a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (!mDisconnected) { 370a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mOwner.hangup(this); 371a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else { 372a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville throw new CallStateException ("disconnected"); 373a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 374a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 375a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 376a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville @Override 377a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public void separate() throws CallStateException { 378a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville throw new CallStateException ("not supported"); 379a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 380a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 381a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville @Override 382a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public void proceedAfterWaitChar() { 383a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (mPostDialState != PostDialState.WAIT) { 384a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Rlog.w(LOG_TAG, "ImsPhoneConnection.proceedAfterWaitChar(): Expected " 385a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville + "getPostDialState() to be WAIT but was " + mPostDialState); 386a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return; 387a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 388a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 389a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville setPostDialState(PostDialState.STARTED); 390a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 391a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville processNextPostDialChar(); 392a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 393a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 394a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville @Override 395a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public void proceedAfterWildChar(String str) { 396a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (mPostDialState != PostDialState.WILD) { 397a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Rlog.w(LOG_TAG, "ImsPhoneConnection.proceedAfterWaitChar(): Expected " 398a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville + "getPostDialState() to be WILD but was " + mPostDialState); 399a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return; 400a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 401a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 402a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville setPostDialState(PostDialState.STARTED); 403a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 404a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // make a new postDialString, with the wild char replacement string 405a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // at the beginning, followed by the remaining postDialString. 406a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 407a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville StringBuilder buf = new StringBuilder(str); 408a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville buf.append(mPostDialString.substring(mNextPostDialChar)); 409a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mPostDialString = buf.toString(); 410a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mNextPostDialChar = 0; 411a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (Phone.DEBUG_PHONE) { 412a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Rlog.d(LOG_TAG, "proceedAfterWildChar: new postDialString is " + 413a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mPostDialString); 414a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 415a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 416a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville processNextPostDialChar(); 417a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 418a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 419a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville @Override 420a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public void cancelPostDial() { 421a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville setPostDialState(PostDialState.CANCELLED); 422a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 423a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 424a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville /** 425a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * Called when this Connection is being hung up locally (eg, user pressed "end") 426a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville */ 427a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville void 428a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville onHangupLocal() { 429a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mCause = DisconnectCause.LOCAL; 430a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 431a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 432a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville /** Called when the connection has been disconnected */ 433c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajan @Override 434c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajan public boolean onDisconnect(int cause) { 435a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Rlog.d(LOG_TAG, "onDisconnect: cause=" + cause); 4361999b9772eb9b3a230bd2520ffebb152544eaba9Tyler Gunn if (mCause != DisconnectCause.LOCAL || cause == DisconnectCause.INCOMING_REJECTED) { 4371999b9772eb9b3a230bd2520ffebb152544eaba9Tyler Gunn mCause = cause; 4381999b9772eb9b3a230bd2520ffebb152544eaba9Tyler Gunn } 439a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return onDisconnect(); 440a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 441a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 442f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxu public boolean onDisconnect() { 443a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville boolean changed = false; 444a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 445a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (!mDisconnected) { 446a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville //mIndex = -1; 447a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 448a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mDisconnectTime = System.currentTimeMillis(); 449a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mDuration = SystemClock.elapsedRealtime() - mConnectTimeReal; 450a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mDisconnected = true; 451a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 452a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mOwner.mPhone.notifyDisconnect(this); 45347b078c27bfb57477a4ff1ce12abc4e9632c1dd5Tyler Gunn notifyDisconnect(mCause); 454a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 455a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (mParent != null) { 456a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville changed = mParent.connectionDisconnected(this); 457a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else { 458a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Rlog.d(LOG_TAG, "onDisconnect: no parent"); 459a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 46034310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu synchronized (this) { 46134310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu if (mImsCall != null) mImsCall.close(); 46234310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu mImsCall = null; 46334310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu } 464a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 465a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville releaseWakeLock(); 466a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return changed; 467a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 468a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 469a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville /** 470a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * An incoming or outgoing call has connected 471a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville */ 472a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville void 473a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville onConnectedInOrOut() { 474a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mConnectTime = System.currentTimeMillis(); 475a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mConnectTimeReal = SystemClock.elapsedRealtime(); 476a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mDuration = 0; 477a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 478a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (Phone.DEBUG_PHONE) { 479a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Rlog.d(LOG_TAG, "onConnectedInOrOut: connectTime=" + mConnectTime); 480a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 481a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 482a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (!mIsIncoming) { 483a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // outgoing calls only 484a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville processNextPostDialChar(); 485a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 486a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville releaseWakeLock(); 487a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 488a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 489a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville /*package*/ void 490a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville onStartedHolding() { 491a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mHoldingStartTime = SystemClock.elapsedRealtime(); 492a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 493a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville /** 494a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * Performs the appropriate action for a post-dial char, but does not 495a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * notify application. returns false if the character is invalid and 496a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * should be ignored 497a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville */ 498a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private boolean 499a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville processPostDialChar(char c) { 500a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (PhoneNumberUtils.is12Key(c)) { 5018a5c54f8ba1793a89bb8e18e819d1fc5b85bc1bfBrad Ebinger Message dtmfComplete = mHandler.obtainMessage(EVENT_DTMF_DONE); 5028a5c54f8ba1793a89bb8e18e819d1fc5b85bc1bfBrad Ebinger dtmfComplete.replyTo = mHandlerMessenger; 5038a5c54f8ba1793a89bb8e18e819d1fc5b85bc1bfBrad Ebinger mOwner.sendDtmf(c, dtmfComplete); 504a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else if (c == PhoneNumberUtils.PAUSE) { 505a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // From TS 22.101: 506a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // It continues... 507a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Upon the called party answering the UE shall send the DTMF digits 508a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // automatically to the network after a delay of 3 seconds( 20 ). 509a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // The digits shall be sent according to the procedures and timing 510a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // specified in 3GPP TS 24.008 [13]. The first occurrence of the 511a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // "DTMF Control Digits Separator" shall be used by the ME to 512a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // distinguish between the addressing digits (i.e. the phone number) 513a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // and the DTMF digits. Upon subsequent occurrences of the 514a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // separator, 515a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // the UE shall pause again for 3 seconds ( 20 ) before sending 516a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // any further DTMF digits. 517a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_PAUSE_DONE), 518a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville PAUSE_DELAY_MILLIS); 519a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else if (c == PhoneNumberUtils.WAIT) { 520a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville setPostDialState(PostDialState.WAIT); 521a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else if (c == PhoneNumberUtils.WILD) { 522a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville setPostDialState(PostDialState.WILD); 523a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else { 524a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return false; 525a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 526a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 527a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return true; 528a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 529a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 530a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville @Override 531032d73c15281387a97cdb91c6f0c7c3a1b1b230eAmit Mahajan protected void finalize() { 532a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville releaseWakeLock(); 533a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 534a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 535a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private void 536a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville processNextPostDialChar() { 537a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville char c = 0; 538a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Registrant postDialHandler; 539a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 540a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (mPostDialState == PostDialState.CANCELLED) { 541a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville //Rlog.d(LOG_TAG, "##### processNextPostDialChar: postDialState == CANCELLED, bail"); 542a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return; 543a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 544a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 545d9aa1a75304b1c04c352198b9269f40a2a059f74Andrew Lee if (mPostDialString == null || mPostDialString.length() <= mNextPostDialChar) { 546a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville setPostDialState(PostDialState.COMPLETE); 547a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 548a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // notifyMessage.arg1 is 0 on complete 549a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville c = 0; 550a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else { 551a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville boolean isValid; 552a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 553a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville setPostDialState(PostDialState.STARTED); 554a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 555a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville c = mPostDialString.charAt(mNextPostDialChar++); 556a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 557a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville isValid = processPostDialChar(c); 558a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 559a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (!isValid) { 560a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Will call processNextPostDialChar 561a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mHandler.obtainMessage(EVENT_NEXT_POST_DIAL).sendToTarget(); 562a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Don't notify application 563a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Rlog.e(LOG_TAG, "processNextPostDialChar: c=" + c + " isn't valid!"); 564a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return; 565a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 566a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 567a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 5684567a0789e9966929c71af9a2c3866582c85c9e0Nancy Chen notifyPostDialListenersNextChar(c); 5694567a0789e9966929c71af9a2c3866582c85c9e0Nancy Chen 5704567a0789e9966929c71af9a2c3866582c85c9e0Nancy Chen // TODO: remove the following code since the handler no longer executes anything. 57193c62c8a71821f46194e16ca3e84f95e101edb90Amit Mahajan postDialHandler = mOwner.mPhone.getPostDialHandler(); 572a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 573a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Message notifyMessage; 574a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 575a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (postDialHandler != null 576a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville && (notifyMessage = postDialHandler.messageForRegistrant()) != null) { 577a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // The AsyncResult.result is the Connection object 578a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville PostDialState state = mPostDialState; 579a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville AsyncResult ar = AsyncResult.forMessage(notifyMessage); 580a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville ar.result = this; 581a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville ar.userObj = state; 582a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 583a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // arg1 is the character that was/is being processed 584a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville notifyMessage.arg1 = c; 585a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 586d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati //Rlog.v(LOG_TAG, 587d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati // "##### processNextPostDialChar: send msg to postDialHandler, arg1=" + c); 588a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville notifyMessage.sendToTarget(); 589a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 590a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 591a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 592a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville /** 593a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * Set post dial state and acquire wake lock while switching to "started" 594a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * state, the wake lock will be released if state switches out of "started" 595a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * state or after WAKE_LOCK_TIMEOUT_MILLIS. 596a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * @param s new PostDialState 597a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville */ 598a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private void setPostDialState(PostDialState s) { 599a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (mPostDialState != PostDialState.STARTED 600a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville && s == PostDialState.STARTED) { 601a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville acquireWakeLock(); 602a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Message msg = mHandler.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT); 603a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mHandler.sendMessageDelayed(msg, WAKE_LOCK_TIMEOUT_MILLIS); 604a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else if (mPostDialState == PostDialState.STARTED 605a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville && s != PostDialState.STARTED) { 606a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mHandler.removeMessages(EVENT_WAKE_LOCK_TIMEOUT); 607a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville releaseWakeLock(); 608a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 609a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mPostDialState = s; 610d9aa1a75304b1c04c352198b9269f40a2a059f74Andrew Lee notifyPostDialListeners(); 611a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 612a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 613a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private void 614a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville createWakeLock(Context context) { 615a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); 616a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG); 617a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 618a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 619a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville private void 620a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville acquireWakeLock() { 621a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Rlog.d(LOG_TAG, "acquireWakeLock"); 622a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mPartialWakeLock.acquire(); 623a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 624a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 62597fba207643a87dd718395010a98ded3e809a3d7Libin.Tang@motorola.com void 626a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville releaseWakeLock() { 62737800d3cdb300fca83462d95221a05bbef21a951Amit Mahajan if (mPartialWakeLock != null) { 62837800d3cdb300fca83462d95221a05bbef21a951Amit Mahajan synchronized (mPartialWakeLock) { 62937800d3cdb300fca83462d95221a05bbef21a951Amit Mahajan if (mPartialWakeLock.isHeld()) { 63037800d3cdb300fca83462d95221a05bbef21a951Amit Mahajan Rlog.d(LOG_TAG, "releaseWakeLock"); 63137800d3cdb300fca83462d95221a05bbef21a951Amit Mahajan mPartialWakeLock.release(); 63237800d3cdb300fca83462d95221a05bbef21a951Amit Mahajan } 633a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 634a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 635a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 636a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 637c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajan private void fetchDtmfToneDelay(Phone phone) { 6386bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius CarrierConfigManager configMgr = (CarrierConfigManager) 6396bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE); 6406bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius PersistableBundle b = configMgr.getConfigForSubId(phone.getSubId()); 6416bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius if (b != null) { 6426bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius mDtmfToneDelay = b.getInt(CarrierConfigManager.KEY_IMS_DTMF_TONE_DELAY_INT); 6436bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius } 6446bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius } 6456bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius 646a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville @Override 647a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public int getNumberPresentation() { 648a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return mNumberPresentation; 649a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 650a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 651a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville @Override 652a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public UUSInfo getUUSInfo() { 653a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return mUusInfo; 654a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 655a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 656a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville @Override 657a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public Connection getOrigConnection() { 658a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return null; 659a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 660a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 661a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville @Override 66234310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu public synchronized boolean isMultiparty() { 663541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn return mImsCall != null && mImsCall.isMultiparty(); 664a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 665a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 666ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn /** 667ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn * Where {@link #isMultiparty()} is {@code true}, determines if this {@link ImsCall} is the 668ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn * origin of the conference call (i.e. {@code #isConferenceHost()} is {@code true}), or if this 669ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn * {@link ImsCall} is a member of a conference hosted on another device. 670ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn * 671ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn * @return {@code true} if this call is the origin of the conference call it is a member of, 672ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn * {@code false} otherwise. 673ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn */ 674c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajan @Override 67534310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu public synchronized boolean isConferenceHost() { 67634310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu return mImsCall != null && mImsCall.isConferenceHost(); 677ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn } 678ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn 679c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajan @Override 680c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajan public boolean isMemberOfPeerConference() { 681c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajan return !isConferenceHost(); 682c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajan } 683c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajan 68434310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu public synchronized ImsCall getImsCall() { 685a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return mImsCall; 686a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 687a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 68834310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu public synchronized void setImsCall(ImsCall imsCall) { 689a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mImsCall = imsCall; 690a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 691a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 692f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxu public void changeParent(ImsPhoneCall parent) { 693a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mParent = parent; 694a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 695a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 6966a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee /** 6976a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee * @return {@code true} if the {@link ImsPhoneConnection} or its media capabilities have been 6986a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee * changed, and {@code false} otherwise. 6996a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee */ 700f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxu public boolean update(ImsCall imsCall, ImsPhoneCall.State state) { 701a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (state == ImsPhoneCall.State.ACTIVE) { 702707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn // If the state of the call is active, but there is a pending request to the RIL to hold 703707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn // the call, we will skip this update. This is really a signalling delay or failure 704707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn // from the RIL, but we will prevent it from going through as we will end up erroneously 705707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn // making this call active when really it should be on hold. 706707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn if (imsCall.isPendingHold()) { 707707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn Rlog.w(LOG_TAG, "update : state is ACTIVE, but call is pending hold, skipping"); 708707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn return false; 709707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn } 710707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn 7116a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee if (mParent.getState().isRinging() || mParent.getState().isDialing()) { 712a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville onConnectedInOrOut(); 713a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 714a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 7156a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee if (mParent.getState().isRinging() || mParent == mOwner.mBackgroundCall) { 716a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville //mForegroundCall should be IDLE 717a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville //when accepting WAITING call 718a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville //before accept WAITING call, 719a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville //the ACTIVE call should be held ahead 720a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mParent.detach(this); 721a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mParent = mOwner.mForegroundCall; 722a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville mParent.attach(this); 723a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 724a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else if (state == ImsPhoneCall.State.HOLDING) { 725a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville onStartedHolding(); 726a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 727a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 728549148fb25d8b38c2bd1207c1a21027c6621932bEtan Cohen boolean updateParent = mParent.update(this, imsCall, state); 729eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh boolean updateAddressDisplay = updateAddressDisplay(imsCall); 73021048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar boolean updateMediaCapabilities = updateMediaCapabilities(imsCall); 73121048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar boolean updateExtras = updateExtras(imsCall); 732ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn 73375f96a40e73bbf262287b64f7ba79f058adac472Brad Ebinger return updateParent || updateAddressDisplay || updateMediaCapabilities || updateExtras; 734a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 735a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 736a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville @Override 737a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville public int getPreciseDisconnectCause() { 738222bd9d64068a23f5470561655ca4dbd2359eeceJayachandran C return mPreciseDisconnectCause; 739222bd9d64068a23f5470561655ca4dbd2359eeceJayachandran C } 740222bd9d64068a23f5470561655ca4dbd2359eeceJayachandran C 741222bd9d64068a23f5470561655ca4dbd2359eeceJayachandran C public void setPreciseDisconnectCause(int cause) { 742222bd9d64068a23f5470561655ca4dbd2359eeceJayachandran C mPreciseDisconnectCause = cause; 743a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 744d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn 745d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn /** 746d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn * Notifies this Connection of a request to disconnect a participant of the conference managed 747d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn * by the connection. 748d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn * 749d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn * @param endpoint the {@link android.net.Uri} of the participant to disconnect. 750d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn */ 751d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn @Override 752d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn public void onDisconnectConferenceParticipant(Uri endpoint) { 753d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn ImsCall imsCall = getImsCall(); 754d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn if (imsCall == null) { 755d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn return; 756d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn } 757d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn try { 758d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn imsCall.removeParticipants(new String[]{endpoint.toString()}); 759d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn } catch (ImsException e) { 760d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn // No session in place -- no change 761d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn Rlog.e(LOG_TAG, "onDisconnectConferenceParticipant: no session in place. "+ 762d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn "Failed to disconnect endpoint = " + endpoint); 763d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn } 764d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn } 765541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn 766541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn /** 767fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn * Sets the conference connect time. Used when an {@code ImsConference} is created to out of 768fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn * this phone connection. 769fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn * 770fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn * @param conferenceConnectTime The conference connect time. 771fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn */ 772fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn public void setConferenceConnectTime(long conferenceConnectTime) { 773fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn mConferenceConnectTime = conferenceConnectTime; 774fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn } 775fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn 776fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn /** 777fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn * @return The conference connect time. 778fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn */ 779fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn public long getConferenceConnectTime() { 780fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn return mConferenceConnectTime; 781fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn } 782fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn 783fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn /** 784eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh * Check for a change in the address display related fields for the {@link ImsCall}, and 785eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh * update the {@link ImsPhoneConnection} with this information. 786eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh * 787eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh * @param imsCall The call to check for changes in address display fields. 788eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh * @return Whether the address display fields have been changed. 789eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh */ 79027e0378194d55fdcb23f4a3a85dc620a234b5855Anju Mathapati public boolean updateAddressDisplay(ImsCall imsCall) { 791eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh if (imsCall == null) { 792eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh return false; 793eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh } 794eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh 795eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh boolean changed = false; 796eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh ImsCallProfile callProfile = imsCall.getCallProfile(); 797eb7465409290618ca5d7b5f8ba2ffabba2d936d9Tyler Gunn if (callProfile != null && isIncoming()) { 798eb7465409290618ca5d7b5f8ba2ffabba2d936d9Tyler Gunn // Only look for changes to the address for incoming calls. The originating identity 799eb7465409290618ca5d7b5f8ba2ffabba2d936d9Tyler Gunn // can change for outgoing calls due to, for example, a call being forwarded to 800eb7465409290618ca5d7b5f8ba2ffabba2d936d9Tyler Gunn // voicemail. This address change does not need to be presented to the user. 801eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh String address = callProfile.getCallExtra(ImsCallProfile.EXTRA_OI); 802eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh String name = callProfile.getCallExtra(ImsCallProfile.EXTRA_CNA); 803eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh int nump = ImsCallProfile.OIRToPresentation( 804eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh callProfile.getCallExtraInt(ImsCallProfile.EXTRA_OIR)); 805eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh int namep = ImsCallProfile.OIRToPresentation( 806eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh callProfile.getCallExtraInt(ImsCallProfile.EXTRA_CNAP)); 807eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh if (Phone.DEBUG_PHONE) { 808eb7465409290618ca5d7b5f8ba2ffabba2d936d9Tyler Gunn Rlog.d(LOG_TAG, "updateAddressDisplay: callId = " + getTelecomCallId() 809c58281f18e760c39c2fedba61453eae7bfdda349Xinying.Deng + " address = " + Rlog.pii(LOG_TAG, address) + " name = " 810c58281f18e760c39c2fedba61453eae7bfdda349Xinying.Deng + Rlog.pii(LOG_TAG, name) + " nump = " + nump + " namep = " + namep); 811eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh } 812286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn if (!mIsMergeInProcess) { 813286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn // Only process changes to the name and address when a merge is not in process. 814286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn // When call A initiated a merge with call B to form a conference C, there is a 815286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn // point in time when the ImsCall transfers the conference call session into A, 816286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn // at which point the ImsConferenceController creates the conference in Telecom. 817286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn // For some carriers C will have a unique conference URI address. Swapping the 818286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn // conference session into A, which is about to be disconnected, to be logged to 819286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn // the call log using the conference address. To prevent this we suppress updates 820286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn // to the call address while a merge is in process. 821286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn if (!equalsBaseDialString(mAddress, address)) { 822286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn mAddress = address; 823286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn changed = true; 824286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn } 825286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn if (TextUtils.isEmpty(name)) { 826286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn if (!TextUtils.isEmpty(mCnapName)) { 827286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn mCnapName = ""; 828286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn changed = true; 829286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn } 830286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn } else if (!name.equals(mCnapName)) { 831286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn mCnapName = name; 832286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn changed = true; 833286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn } 834286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn if (mNumberPresentation != nump) { 835286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn mNumberPresentation = nump; 836286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn changed = true; 837286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn } 838286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn if (mCnapNamePresentation != namep) { 839286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn mCnapNamePresentation = namep; 840eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh changed = true; 841eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh } 842eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh } 843eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh } 844eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh return changed; 845eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh } 846eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh 847eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh /** 8486a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee * Check for a change in the video capabilities and audio quality for the {@link ImsCall}, and 8496a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee * update the {@link ImsPhoneConnection} with this information. 8506a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee * 8516a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee * @param imsCall The call to check for changes in media capabilities. 8526a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee * @return Whether the media capabilities have been changed. 8536a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee */ 854d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati public boolean updateMediaCapabilities(ImsCall imsCall) { 8556a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee if (imsCall == null) { 8566a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee return false; 8576a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee } 8586a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee 8596a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee boolean changed = false; 8606a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee 8616a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee try { 862e70972cf6a3b48df1f7d036877eb28529e606ca9Tyler Gunn // The actual call profile (negotiated between local and peer). 863e70972cf6a3b48df1f7d036877eb28529e606ca9Tyler Gunn ImsCallProfile negotiatedCallProfile = imsCall.getCallProfile(); 8646a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee 865e70972cf6a3b48df1f7d036877eb28529e606ca9Tyler Gunn if (negotiatedCallProfile != null) { 866288268d5528e0df03f348e303954813cb188c55bRekha Kumar int oldVideoState = getVideoState(); 867288268d5528e0df03f348e303954813cb188c55bRekha Kumar int newVideoState = ImsCallProfile 868288268d5528e0df03f348e303954813cb188c55bRekha Kumar .getVideoStateFromImsCallProfile(negotiatedCallProfile); 869e70972cf6a3b48df1f7d036877eb28529e606ca9Tyler Gunn 870288268d5528e0df03f348e303954813cb188c55bRekha Kumar if (oldVideoState != newVideoState) { 871db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // The video state has changed. See also code in onReceiveSessionModifyResponse 872db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // below. When the video enters a paused state, subsequent changes to the video 873db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // state will not be reported by the modem. In onReceiveSessionModifyResponse 874db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // we will be updating the current video state while paused to include any 875db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // changes the modem reports via the video provider. When the video enters an 876db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // unpaused state, we will resume passing the video states from the modem as is. 877db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn if (VideoProfile.isPaused(oldVideoState) && 878db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn !VideoProfile.isPaused(newVideoState)) { 879db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // Video entered un-paused state; recognize updates from now on; we want to 880db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // ensure that the new un-paused state is propagated to Telecom, so change 881db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // this now. 882db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn mShouldIgnoreVideoStateChanges = false; 883db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn } 884db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn 885db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn if (!mShouldIgnoreVideoStateChanges) { 88644b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn updateVideoState(newVideoState); 887db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn changed = true; 888db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn } else { 889db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn Rlog.d(LOG_TAG, "updateMediaCapabilities - ignoring video state change " + 890db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn "due to paused state."); 891db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn } 892db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn 893db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn if (!VideoProfile.isPaused(oldVideoState) && 894db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn VideoProfile.isPaused(newVideoState)) { 895db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // Video entered pause state; ignore updates until un-paused. We do this 896db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // after setVideoState is called above to ensure Telecom is notified that 897db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // the device has entered paused state. 898db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn mShouldIgnoreVideoStateChanges = true; 899db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn } 900e70972cf6a3b48df1f7d036877eb28529e606ca9Tyler Gunn } 90173225469bc0503fe961b2791fa37c855c8243217Hall Liu 90273225469bc0503fe961b2791fa37c855c8243217Hall Liu if (negotiatedCallProfile.mMediaProfile != null) { 9033d28f89927137ce03128a0244a698ca5162e8165Hall Liu mIsRttEnabledForCall = negotiatedCallProfile.mMediaProfile.isRttCall(); 90473225469bc0503fe961b2791fa37c855c8243217Hall Liu 9053d28f89927137ce03128a0244a698ca5162e8165Hall Liu if (mIsRttEnabledForCall && mRttTextHandler == null) { 90673225469bc0503fe961b2791fa37c855c8243217Hall Liu Rlog.d(LOG_TAG, "updateMediaCapabilities -- turning RTT on, profile=" 90773225469bc0503fe961b2791fa37c855c8243217Hall Liu + negotiatedCallProfile); 90873225469bc0503fe961b2791fa37c855c8243217Hall Liu startRttTextProcessing(); 90973225469bc0503fe961b2791fa37c855c8243217Hall Liu onRttInitiated(); 91073225469bc0503fe961b2791fa37c855c8243217Hall Liu changed = true; 9113d28f89927137ce03128a0244a698ca5162e8165Hall Liu } else if (!mIsRttEnabledForCall && mRttTextHandler != null) { 91273225469bc0503fe961b2791fa37c855c8243217Hall Liu Rlog.d(LOG_TAG, "updateMediaCapabilities -- turning RTT off, profile=" 91373225469bc0503fe961b2791fa37c855c8243217Hall Liu + negotiatedCallProfile); 91473225469bc0503fe961b2791fa37c855c8243217Hall Liu mRttTextHandler.tearDown(); 91573225469bc0503fe961b2791fa37c855c8243217Hall Liu mRttTextHandler = null; 91673225469bc0503fe961b2791fa37c855c8243217Hall Liu onRttTerminated(); 91773225469bc0503fe961b2791fa37c855c8243217Hall Liu changed = true; 91873225469bc0503fe961b2791fa37c855c8243217Hall Liu } 91973225469bc0503fe961b2791fa37c855c8243217Hall Liu } 920e70972cf6a3b48df1f7d036877eb28529e606ca9Tyler Gunn } 921e70972cf6a3b48df1f7d036877eb28529e606ca9Tyler Gunn 922f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn // Check for a change in the capabilities for the call and update 923f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn // {@link ImsPhoneConnection} with this information. 924f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn int capabilities = getConnectionCapabilities(); 9252e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn 9262e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn // Use carrier config to determine if downgrading directly to audio-only is supported. 9272e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn if (mOwner.isCarrierDowngradeOfVtCallSupported()) { 9282e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn capabilities = addCapability(capabilities, 9292e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn Connection.Capability.SUPPORTS_DOWNGRADE_TO_VOICE_REMOTE | 9302e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn Capability.SUPPORTS_DOWNGRADE_TO_VOICE_LOCAL); 9312e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn } else { 9322e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn capabilities = removeCapability(capabilities, 9332e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn Connection.Capability.SUPPORTS_DOWNGRADE_TO_VOICE_REMOTE | 9342e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn Capability.SUPPORTS_DOWNGRADE_TO_VOICE_LOCAL); 9352e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn } 9362e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn 937f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn // Get the current local call capabilities which might be voice or video or both. 938f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn ImsCallProfile localCallProfile = imsCall.getLocalCallProfile(); 939f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn Rlog.v(LOG_TAG, "update localCallProfile=" + localCallProfile); 9406a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee if (localCallProfile != null) { 941f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn capabilities = applyLocalCallCapabilities(localCallProfile, capabilities); 9426a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee } 9436a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee 944f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn // Get the current remote call capabilities which might be voice or video or both. 945f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn ImsCallProfile remoteCallProfile = imsCall.getRemoteCallProfile(); 946f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn Rlog.v(LOG_TAG, "update remoteCallProfile=" + remoteCallProfile); 947288268d5528e0df03f348e303954813cb188c55bRekha Kumar if (remoteCallProfile != null) { 948f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn capabilities = applyRemoteCallCapabilities(remoteCallProfile, capabilities); 949f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn } 950f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn if (getConnectionCapabilities() != capabilities) { 951f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn setConnectionCapabilities(capabilities); 952f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn changed = true; 953288268d5528e0df03f348e303954813cb188c55bRekha Kumar } 954288268d5528e0df03f348e303954813cb188c55bRekha Kumar 9556a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee int newAudioQuality = 9566a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee getAudioQualityFromCallProfile(localCallProfile, remoteCallProfile); 9576a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee if (getAudioQuality() != newAudioQuality) { 9586a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee setAudioQuality(newAudioQuality); 9596a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee changed = true; 9606a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee } 9616a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee } catch (ImsException e) { 9626a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee // No session in place -- no change 9636a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee } 9646a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee 9656a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee return changed; 9666a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee } 9676a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee 96844b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn private void updateVideoState(int newVideoState) { 96944b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn if (mImsVideoCallProviderWrapper != null) { 97044b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn mImsVideoCallProviderWrapper.onVideoStateChanged(newVideoState); 97144b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn } 97244b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn setVideoState(newVideoState); 97344b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn } 97444b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn 975fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu public void sendRttModifyRequest(android.telecom.Connection.RttTextStream textStream) { 976fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu getImsCall().sendRttModifyRequest(); 977fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu setCurrentRttTextStream(textStream); 978fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu } 979fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu 980fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu /** 981fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu * Sends the user's response to a remotely-issued RTT upgrade request 982fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu * 983fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu * @param textStream A valid {@link android.telecom.Connection.RttTextStream} if the user 984fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu * accepts, {@code null} if not. 985fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu */ 986fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu public void sendRttModifyResponse(android.telecom.Connection.RttTextStream textStream) { 987fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu boolean accept = textStream != null; 988fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu ImsCall imsCall = getImsCall(); 989fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu 990fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu imsCall.sendRttModifyResponse(accept); 991fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu if (accept) { 992fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu setCurrentRttTextStream(textStream); 993fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu } else { 994fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu Rlog.e(LOG_TAG, "sendRttModifyResponse: foreground call has no connections"); 995fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu } 996fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu } 997fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu 998fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu public void onRttMessageReceived(String message) { 999670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu synchronized (this) { 1000670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu if (mRttTextHandler == null) { 1001670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu Rlog.w(LOG_TAG, "onRttMessageReceived: RTT text handler not available." 1002670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu + " Attempting to create one."); 1003670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu if (mRttTextStream == null) { 1004670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu Rlog.e(LOG_TAG, "onRttMessageReceived:" 1005670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu + " Unable to process incoming message. No textstream available"); 1006670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu return; 1007670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu } 1008670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu createRttTextHandler(); 1009670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu } 1010670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu } 1011670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu mRttTextHandler.sendToInCall(message); 1012fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu } 1013fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu 1014fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu public void setCurrentRttTextStream(android.telecom.Connection.RttTextStream rttTextStream) { 1015670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu synchronized (this) { 1016670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu mRttTextStream = rttTextStream; 1017670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu if (mRttTextHandler == null && mIsRttEnabledForCall) { 1018670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu Rlog.i(LOG_TAG, "setCurrentRttTextStream: Creating a text handler"); 1019670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu createRttTextHandler(); 1020670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu } 1021670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu } 1022fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu } 1023fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu 102473225469bc0503fe961b2791fa37c855c8243217Hall Liu public boolean hasRttTextStream() { 102573225469bc0503fe961b2791fa37c855c8243217Hall Liu return mRttTextStream != null; 102673225469bc0503fe961b2791fa37c855c8243217Hall Liu } 102773225469bc0503fe961b2791fa37c855c8243217Hall Liu 10283d28f89927137ce03128a0244a698ca5162e8165Hall Liu public boolean isRttEnabledForCall() { 10293d28f89927137ce03128a0244a698ca5162e8165Hall Liu return mIsRttEnabledForCall; 10303d28f89927137ce03128a0244a698ca5162e8165Hall Liu } 10313d28f89927137ce03128a0244a698ca5162e8165Hall Liu 1032fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu public void startRttTextProcessing() { 1033670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu synchronized (this) { 1034670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu if (mRttTextStream == null) { 1035670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu Rlog.w(LOG_TAG, "startRttTextProcessing: no RTT text stream. Ignoring."); 1036670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu return; 1037670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu } 1038670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu if (mRttTextHandler != null) { 1039670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu Rlog.w(LOG_TAG, "startRttTextProcessing: RTT text handler already exists"); 1040670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu return; 1041670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu } 1042670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu createRttTextHandler(); 104373225469bc0503fe961b2791fa37c855c8243217Hall Liu } 1044fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu } 1045fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu 1046670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu // Make sure to synchronize on ImsPhoneConnection.this before calling. 1047670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu private void createRttTextHandler() { 1048fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu mRttTextHandler = new ImsRttTextHandler(Looper.getMainLooper(), 1049fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu (message) -> getImsCall().sendRttMessage(message)); 1050670f3a47cde0e3410f756927f00d03ee2ef881dcHall Liu mRttTextHandler.initialize(mRttTextStream); 1051fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu } 1052fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu 10536a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee /** 10542e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn * Updates the wifi state based on the {@link ImsCallProfile#EXTRA_CALL_RAT_TYPE}. 10552e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn * The call is considered to be a WIFI call if the extra value is 10562e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn * {@link ServiceState#RIL_RADIO_TECHNOLOGY_IWLAN}. 10572e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn * 10582e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn * @param extras The ImsCallProfile extras. 10592e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn */ 10602e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn private void updateWifiStateFromExtras(Bundle extras) { 1061d0a85e9d7e52ecd5de9f7063361d9b01d2493627Brad Ebinger if (extras.containsKey(ImsCallProfile.EXTRA_CALL_RAT_TYPE) || 1062d0a85e9d7e52ecd5de9f7063361d9b01d2493627Brad Ebinger extras.containsKey(ImsCallProfile.EXTRA_CALL_RAT_TYPE_ALT)) { 10632e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn 1064d0a85e9d7e52ecd5de9f7063361d9b01d2493627Brad Ebinger ImsCall call = getImsCall(); 1065d0a85e9d7e52ecd5de9f7063361d9b01d2493627Brad Ebinger boolean isWifi = false; 1066d0a85e9d7e52ecd5de9f7063361d9b01d2493627Brad Ebinger if (call != null) { 1067d0a85e9d7e52ecd5de9f7063361d9b01d2493627Brad Ebinger isWifi = call.isWifiCall(); 1068d0a85e9d7e52ecd5de9f7063361d9b01d2493627Brad Ebinger } 10692e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn 10702e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn // Report any changes 10712e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn if (isWifi() != isWifi) { 10722e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn setWifi(isWifi); 10732e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn } 10742e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn } 10752e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn } 10762e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn 10772e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn /** 107821048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar * Check for a change in call extras of {@link ImsCall}, and 107921048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar * update the {@link ImsPhoneConnection} accordingly. 108021048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar * 108121048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar * @param imsCall The call to check for changes in extras. 108221048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar * @return Whether the extras fields have been changed. 108321048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar */ 108421048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar boolean updateExtras(ImsCall imsCall) { 108521048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar if (imsCall == null) { 108621048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar return false; 108721048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar } 108821048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar 108921048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar final ImsCallProfile callProfile = imsCall.getCallProfile(); 109021048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar final Bundle extras = callProfile != null ? callProfile.mCallExtras : null; 109121048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar if (extras == null && DBG) { 109221048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar Rlog.d(LOG_TAG, "Call profile extras are null."); 109321048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar } 109421048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar 109521048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar final boolean changed = !areBundlesEqual(extras, mExtras); 109621048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar if (changed) { 10972e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn updateWifiStateFromExtras(extras); 10982e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn 109921048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar mExtras.clear(); 110021048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar mExtras.putAll(extras); 110121048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar setConnectionExtras(mExtras); 110221048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar } 110321048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar return changed; 110421048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar } 110521048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar 110621048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar private static boolean areBundlesEqual(Bundle extras, Bundle newExtras) { 110721048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar if (extras == null || newExtras == null) { 110821048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar return extras == newExtras; 110921048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar } 111021048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar 111121048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar if (extras.size() != newExtras.size()) { 111221048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar return false; 111321048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar } 111421048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar 111521048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar for(String key : extras.keySet()) { 111621048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar if (key != null) { 111721048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar final Object value = extras.get(key); 111821048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar final Object newValue = newExtras.get(key); 111921048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar if (!Objects.equals(value, newValue)) { 112021048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar return false; 112121048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar } 112221048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar } 112321048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar } 112421048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar return true; 112521048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar } 112621048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar 112721048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar /** 11286a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee * Determines the {@link ImsPhoneConnection} audio quality based on the local and remote 1129363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty * {@link ImsCallProfile}. Indicate a HD audio call if the local stream profile 1130363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty * is AMR_WB, EVRC_WB, EVS_WB, EVS_SWB, EVS_FB and 1131363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty * there is no remote restrict cause. 11326a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee * 11336a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee * @param localCallProfile The local call profile. 11346a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee * @param remoteCallProfile The remote call profile. 11356a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee * @return The audio quality. 11366a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee */ 11376a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee private int getAudioQualityFromCallProfile( 11386a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee ImsCallProfile localCallProfile, ImsCallProfile remoteCallProfile) { 11396a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee if (localCallProfile == null || remoteCallProfile == null 11406a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee || localCallProfile.mMediaProfile == null) { 11416a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee return AUDIO_QUALITY_STANDARD; 11426a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee } 11436a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee 1144363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty final boolean isEvsCodecHighDef = (localCallProfile.mMediaProfile.mAudioQuality 1145363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty == ImsStreamMediaProfile.AUDIO_QUALITY_EVS_WB 1146363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty || localCallProfile.mMediaProfile.mAudioQuality 1147363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty == ImsStreamMediaProfile.AUDIO_QUALITY_EVS_SWB 1148363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty || localCallProfile.mMediaProfile.mAudioQuality 1149363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty == ImsStreamMediaProfile.AUDIO_QUALITY_EVS_FB); 1150363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty 1151363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty final boolean isHighDef = (localCallProfile.mMediaProfile.mAudioQuality 11526a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee == ImsStreamMediaProfile.AUDIO_QUALITY_AMR_WB 11536a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee || localCallProfile.mMediaProfile.mAudioQuality 1154363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty == ImsStreamMediaProfile.AUDIO_QUALITY_EVRC_WB 1155363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty || isEvsCodecHighDef) 11566a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee && remoteCallProfile.mRestrictCause == ImsCallProfile.CALL_RESTRICT_CAUSE_NONE; 11576a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee return isHighDef ? AUDIO_QUALITY_HIGH_DEFINITION : AUDIO_QUALITY_STANDARD; 11586a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee } 11596a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee 11606a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee /** 1161541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn * Provides a string representation of the {@link ImsPhoneConnection}. Primarily intended for 1162541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn * use in log statements. 1163541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn * 1164541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn * @return String representation of call. 1165541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn */ 1166541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn @Override 1167541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn public String toString() { 1168541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn StringBuilder sb = new StringBuilder(); 1169541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn sb.append("[ImsPhoneConnection objId: "); 1170541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn sb.append(System.identityHashCode(this)); 11711a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu sb.append(" telecomCallID: "); 11721a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu sb.append(getTelecomCallId()); 11731a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu sb.append(" address: "); 117477a1f167b962ceaf7972d246f4c23e17772d1c69fionaxu sb.append(Rlog.pii(LOG_TAG, getAddress())); 11751a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu sb.append(" ImsCall: "); 117634310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu synchronized (this) { 117734310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu if (mImsCall == null) { 117834310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu sb.append("null"); 117934310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu } else { 118034310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu sb.append(mImsCall); 118134310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu } 1182541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn } 1183541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn sb.append("]"); 1184541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn return sb.toString(); 1185541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn } 11868bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan 1187359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn @Override 1188359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn public void setVideoProvider(android.telecom.Connection.VideoProvider videoProvider) { 1189359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn super.setVideoProvider(videoProvider); 1190359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn 1191359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn if (videoProvider instanceof ImsVideoCallProviderWrapper) { 1192359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn mImsVideoCallProviderWrapper = (ImsVideoCallProviderWrapper) videoProvider; 1193359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn } 1194359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn } 1195359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn 11968bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan /** 11978bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan * Indicates whether current phone connection is emergency or not 11988bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan * @return boolean: true if emergency, false otherwise 11998bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan */ 12008bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan protected boolean isEmergency() { 12018bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan return mIsEmergency; 12028bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan } 1203db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn 1204db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn /** 1205db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn * Handles notifications from the {@link ImsVideoCallProviderWrapper} of session modification 1206db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn * responses received. 1207db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn * 1208db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn * @param status The status of the original request. 1209db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn * @param requestProfile The requested video profile. 1210db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn * @param responseProfile The response upon video profile. 1211db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn */ 1212db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn @Override 1213db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn public void onReceiveSessionModifyResponse(int status, VideoProfile requestProfile, 1214db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn VideoProfile responseProfile) { 1215db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn if (status == android.telecom.Connection.VideoProvider.SESSION_MODIFY_REQUEST_SUCCESS && 1216db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn mShouldIgnoreVideoStateChanges) { 1217db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn int currentVideoState = getVideoState(); 1218db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn int newVideoState = responseProfile.getVideoState(); 1219db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn 1220db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // If the current video state is paused, the modem will not send us any changes to 1221db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // the TX and RX bits of the video state. Until the video is un-paused we will 1222db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // "fake out" the video state by applying the changes that the modem reports via a 1223db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // response. 1224db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn 1225db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // First, find out whether there was a change to the TX or RX bits: 1226db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn int changedBits = currentVideoState ^ newVideoState; 1227db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn changedBits &= VideoProfile.STATE_BIDIRECTIONAL; 1228db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn if (changedBits == 0) { 1229db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // No applicable change, bail out. 1230db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn return; 1231db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn } 1232db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn 1233db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // Turn off any existing bits that changed. 1234db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn currentVideoState &= ~(changedBits & currentVideoState); 1235db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // Turn on any new bits that turned on. 1236db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn currentVideoState |= changedBits & newVideoState; 1237db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn 1238db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn Rlog.d(LOG_TAG, "onReceiveSessionModifyResponse : received " + 1239db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn VideoProfile.videoStateToString(requestProfile.getVideoState()) + 1240db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn " / " + 1241db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn VideoProfile.videoStateToString(responseProfile.getVideoState()) + 1242db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn " while paused ; sending new videoState = " + 1243db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn VideoProfile.videoStateToString(currentVideoState)); 1244db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn setVideoState(currentVideoState); 1245db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn } 1246db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn } 1247359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn 1248359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn /** 1249359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn * Issues a request to pause the video using {@link VideoProfile#STATE_PAUSED} from a source 1250359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn * other than the InCall UI. 1251359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn * 1252359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn * @param source The source of the pause request. 1253359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn */ 1254359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn public void pauseVideo(int source) { 1255359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn if (mImsVideoCallProviderWrapper == null) { 1256359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn return; 1257359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn } 1258359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn 1259359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn mImsVideoCallProviderWrapper.pauseVideo(getVideoState(), source); 1260359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn } 1261359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn 1262359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn /** 1263359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn * Issues a request to resume the video using {@link VideoProfile#STATE_PAUSED} from a source 1264359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn * other than the InCall UI. 1265359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn * 1266359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn * @param source The source of the resume request. 1267359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn */ 1268359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn public void resumeVideo(int source) { 1269359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn if (mImsVideoCallProviderWrapper == null) { 1270359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn return; 1271359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn } 1272359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn 1273359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn mImsVideoCallProviderWrapper.resumeVideo(getVideoState(), source); 1274359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn } 1275359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn 1276359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn /** 1277359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn * Determines if a specified source has issued a pause request. 1278359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn * 1279359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn * @param source The source. 1280359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn * @return {@code true} if the source issued a pause request, {@code false} otherwise. 1281359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn */ 1282359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn public boolean wasVideoPausedFromSource(int source) { 1283359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn if (mImsVideoCallProviderWrapper == null) { 1284359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn return false; 1285359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn } 1286359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn 1287359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn return mImsVideoCallProviderWrapper.wasVideoPausedFromSource(source); 1288359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn } 1289286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn 1290286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn /** 1291286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn * Mark the call as in the process of being merged and inform the UI of the merge start. 1292286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn */ 1293286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn public void handleMergeStart() { 1294286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn mIsMergeInProcess = true; 1295286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn onConnectionEvent(android.telecom.Connection.EVENT_MERGE_START, null); 1296286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn } 1297286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn 1298286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn /** 1299286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn * Mark the call as done merging and inform the UI of the merge start. 1300286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn */ 1301286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn public void handleMergeComplete() { 1302286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn mIsMergeInProcess = false; 1303286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn onConnectionEvent(android.telecom.Connection.EVENT_MERGE_COMPLETE, null); 1304286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn } 130544b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn 130644b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn public void changeToPausedState() { 130744b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn int newVideoState = getVideoState() | VideoProfile.STATE_PAUSED; 130844b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn Rlog.i(LOG_TAG, "ImsPhoneConnection: changeToPausedState - setting paused bit; " 130944b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn + "newVideoState=" + VideoProfile.videoStateToString(newVideoState)); 131044b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn updateVideoState(newVideoState); 13116dee0e40c77ac373820e7e266ff372a481e30befTyler Gunn mShouldIgnoreVideoStateChanges = true; 131244b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn } 131344b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn 131444b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn public void changeToUnPausedState() { 131544b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn int newVideoState = getVideoState() & ~VideoProfile.STATE_PAUSED; 131644b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn Rlog.i(LOG_TAG, "ImsPhoneConnection: changeToUnPausedState - unsetting paused bit; " 131744b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn + "newVideoState=" + VideoProfile.videoStateToString(newVideoState)); 131844b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn updateVideoState(newVideoState); 13196dee0e40c77ac373820e7e266ff372a481e30befTyler Gunn mShouldIgnoreVideoStateChanges = false; 132044b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn } 13217a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn 13227a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn public void handleDataEnabledChange(boolean isDataEnabled) { 13237a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn mIsVideoEnabled = isDataEnabled; 13247a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn Rlog.i(LOG_TAG, "handleDataEnabledChange: isDataEnabled=" + isDataEnabled 13257a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn + "; updating local video availability."); 13267a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn updateMediaCapabilities(getImsCall()); 13277a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn if (mImsVideoCallProviderWrapper != null) { 13287a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn mImsVideoCallProviderWrapper.setIsVideoEnabled( 13297a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn hasCapabilities(Connection.Capability.SUPPORTS_VT_LOCAL_BIDIRECTIONAL)); 13307a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn } 133165cd15597c5e611184a3f4c8ead5f42644fc00d6Tyler Gunn } 1332a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville} 1333