1788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal/* 2788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal * Copyright (C) 2014 The Android Open Source Project 3788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal * 4788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal * Licensed under the Apache License, Version 2.0 (the "License"); 5788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal * you may not use this file except in compliance with the License. 6788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal * You may obtain a copy of the License at 7788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal * 8788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal * http://www.apache.org/licenses/LICENSE-2.0 9788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal * 10788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal * Unless required by applicable law or agreed to in writing, software 11788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal * distributed under the License is distributed on an "AS IS" BASIS, 12788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal * See the License for the specific language governing permissions and 14788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal * limitations under the License. 15788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal */ 16788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal 17788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepalpackage com.android.services.telephony.sip; 18788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal 194ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunnimport android.net.Uri; 207877c7255268c34a71c7d1b4055afabb8fcba04cHall Liuimport android.os.Bundle; 211344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepalimport android.os.Handler; 221344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepalimport android.os.Message; 234d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunnimport android.telecom.AudioState; 244d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunnimport android.telecom.Connection; 254d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunnimport android.telecom.PhoneAccount; 267877c7255268c34a71c7d1b4055afabb8fcba04cHall Liuimport android.telecom.TelecomManager; 2706a98183cc79dd112d9d33cf027977a9d5d3418aTyler Gunnimport android.util.EventLog; 28788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepalimport android.util.Log; 29788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal 301344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepalimport com.android.internal.telephony.Call; 311344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepalimport com.android.internal.telephony.CallStateException; 327877c7255268c34a71c7d1b4055afabb8fcba04cHall Liuimport com.android.internal.telephony.PhoneConstants; 331344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepalimport com.android.internal.telephony.sip.SipPhone; 34aef7a4bc4f85149de427d7506ebe97753b2ca6c2Andrew Leeimport com.android.services.telephony.DisconnectCauseUtil; 351344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal 364ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunnimport java.util.Objects; 37788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal 381344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepalfinal class SipConnection extends Connection { 39788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal private static final String PREFIX = "[SipConnection] "; 406556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon private static final boolean VERBOSE = false; /* STOP SHIP if true */ 41788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal 421344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal private static final int MSG_PRECISE_CALL_STATE_CHANGED = 1; 431344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal 441344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal private final Handler mHandler = new Handler() { 451344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal @Override 461344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal public void handleMessage(Message msg) { 471344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal switch (msg.what) { 481344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal case MSG_PRECISE_CALL_STATE_CHANGED: 4922d32b2b81bba31b6ebd93753a5c1ec39e911981Sailesh Nepal updateState(false); 501344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal break; 511344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 521344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 531344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal }; 541344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal 551344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal private com.android.internal.telephony.Connection mOriginalConnection; 561344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal private Call.State mOriginalConnectionState = Call.State.IDLE; 57788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal 58aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton SipConnection() { 59aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton if (VERBOSE) log("new SipConnection"); 60aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton setInitializing(); 61aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton } 62aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton 63aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton void initialize(com.android.internal.telephony.Connection connection) { 64aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton if (VERBOSE) log("init SipConnection, connection: " + connection); 651344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal mOriginalConnection = connection; 661344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal if (getPhone() != null) { 671344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal getPhone().registerForPreciseCallStateChanged(mHandler, MSG_PRECISE_CALL_STATE_CHANGED, 681344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal null); 691344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 7014bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee updateAddress(); 717877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu setTechnologyTypeExtra(); 72aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton setInitialized(); 73788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal } 74788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal 75788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal @Override 76c927106af6c47ad1f302e13fa8626be83bb46f14Nancy Chen public void onAudioStateChanged(AudioState state) { 77c927106af6c47ad1f302e13fa8626be83bb46f14Nancy Chen if (VERBOSE) log("onAudioStateChanged: " + state); 781344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal if (getPhone() != null) { 791344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal getPhone().setEchoSuppressionEnabled(); 801344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 81788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal } 82788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal 83788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal @Override 84c927106af6c47ad1f302e13fa8626be83bb46f14Nancy Chen public void onStateChanged(int state) { 85c927106af6c47ad1f302e13fa8626be83bb46f14Nancy Chen if (VERBOSE) log("onStateChanged, state: " + Connection.stateToString(state)); 86788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal } 87788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal 88788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal @Override 89ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon public void onPlayDtmfTone(char c) { 90788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal if (VERBOSE) log("onPlayDtmfTone"); 911344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal if (getPhone() != null) { 921344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal getPhone().startDtmf(c); 931344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 94788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal } 95788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal 96788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal @Override 97ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon public void onStopDtmfTone() { 98788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal if (VERBOSE) log("onStopDtmfTone"); 991344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal if (getPhone() != null) { 1001344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal getPhone().stopDtmf(); 1011344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 102788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal } 103788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal 104788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal @Override 105ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon public void onDisconnect() { 106788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal if (VERBOSE) log("onDisconnect"); 1071344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal try { 1081344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal if (getCall() != null && !getCall().isMultiparty()) { 1091344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal getCall().hangup(); 1101344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } else if (mOriginalConnection != null) { 1111344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal mOriginalConnection.hangup(); 1121344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 1131344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } catch (CallStateException e) { 1141344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal log("onDisconnect, exception: " + e); 1151344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 116788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal } 117788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal 118788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal @Override 119ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon public void onSeparate() { 120788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal if (VERBOSE) log("onSeparate"); 1211344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal try { 1221344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal if (mOriginalConnection != null) { 1231344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal mOriginalConnection.separate(); 1241344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 1251344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } catch (CallStateException e) { 1261344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal log("onSeparate, exception: " + e); 1271344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 128788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal } 129788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal 130788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal @Override 131ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon public void onAbort() { 132788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal if (VERBOSE) log("onAbort"); 1331344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal onDisconnect(); 134788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal } 135788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal 136788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal @Override 137ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon public void onHold() { 138788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal if (VERBOSE) log("onHold"); 1391344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal try { 1402c304ad93f8e74e4a14374d6e00a50cd3497d592Kosuge Yuji if (getPhone() != null && getState() == STATE_ACTIVE 1412c304ad93f8e74e4a14374d6e00a50cd3497d592Kosuge Yuji && getPhone().getRingingCall().getState() != Call.State.WAITING) { 1423ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon // Double check with the internal state since a discrepancy in states could mean 1433ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon // that the transactions is already in progress from a previous request. 1443ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon if (mOriginalConnection != null && 1453ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon mOriginalConnection.getState() == Call.State.ACTIVE) { 1463ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon getPhone().switchHoldingAndActive(); 1473ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon } else { 1483ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon log("skipping switch from onHold due to internal state:"); 1493ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon } 1501344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 1511344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } catch (CallStateException e) { 1521344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal log("onHold, exception: " + e); 1531344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 154788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal } 155788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal 156788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal @Override 157ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon public void onUnhold() { 158788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal if (VERBOSE) log("onUnhold"); 1591344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal try { 160caf84dca8bd90016d910198f1b178ac03e82dd07Roshan Pius if (getPhone() != null && getState() == STATE_HOLDING && 161caf84dca8bd90016d910198f1b178ac03e82dd07Roshan Pius getPhone().getForegroundCall().getState() != Call.State.DIALING) { 1623ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon // Double check with the internal state since a discrepancy in states could mean 1633ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon // that the transaction is already in progress from a previous request. 1643ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon if (mOriginalConnection != null && 1653ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon mOriginalConnection.getState() == Call.State.HOLDING) { 1663ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon getPhone().switchHoldingAndActive(); 1673ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon } else { 1683ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon log("skipping switch from onUnHold due to internal state."); 1693ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon } 1701344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 1711344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } catch (CallStateException e) { 1721344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal log("onUnhold, exception: " + e); 1731344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 174788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal } 175788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal 176788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal @Override 177ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon public void onAnswer(int videoState) { 178788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal if (VERBOSE) log("onAnswer"); 1791344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal try { 1801344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal if (isValidRingingCall() && getPhone() != null) { 1810bbcc4f2f0218f451a680b98a62c374bba877c3bAndrew Lee getPhone().acceptCall(videoState); 1821344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 1831344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } catch (CallStateException e) { 1841344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal log("onAnswer, exception: " + e); 18506a98183cc79dd112d9d33cf027977a9d5d3418aTyler Gunn } catch (IllegalStateException e) { 18606a98183cc79dd112d9d33cf027977a9d5d3418aTyler Gunn // Call could not be answered due to an invalid audio-codec offered by the caller. We 18706a98183cc79dd112d9d33cf027977a9d5d3418aTyler Gunn // will reject the call to stop it from ringing. 18806a98183cc79dd112d9d33cf027977a9d5d3418aTyler Gunn log("onAnswer, IllegalStateException: " + e); 18906a98183cc79dd112d9d33cf027977a9d5d3418aTyler Gunn EventLog.writeEvent(0x534e4554, "31752213", -1, "Invalid codec."); 19006a98183cc79dd112d9d33cf027977a9d5d3418aTyler Gunn onReject(); 19106a98183cc79dd112d9d33cf027977a9d5d3418aTyler Gunn } catch (IllegalArgumentException e) { 19206a98183cc79dd112d9d33cf027977a9d5d3418aTyler Gunn // Call could not be answered due to an error parsing the SDP. We will reject the call 19306a98183cc79dd112d9d33cf027977a9d5d3418aTyler Gunn // to stop it from ringing. 19406a98183cc79dd112d9d33cf027977a9d5d3418aTyler Gunn log("onAnswer, IllegalArgumentException: " + e); 19506a98183cc79dd112d9d33cf027977a9d5d3418aTyler Gunn EventLog.writeEvent(0x534e4554, "31752213", -1, "Invalid SDP."); 19606a98183cc79dd112d9d33cf027977a9d5d3418aTyler Gunn onReject(); 1971344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 198788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal } 199788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal 200788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal @Override 201ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon public void onReject() { 202788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal if (VERBOSE) log("onReject"); 2031344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal try { 2041344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal if (isValidRingingCall() && getPhone() != null) { 2051344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal getPhone().rejectCall(); 2061344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 2071344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } catch (CallStateException e) { 2081344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal log("onReject, exception: " + e); 2091344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 210788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal } 211788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal 212788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal @Override 213ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon public void onPostDialContinue(boolean proceed) { 214788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal if (VERBOSE) log("onPostDialContinue, proceed: " + proceed); 2151344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal // SIP doesn't have post dial support. 216788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal } 217788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal 2181344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal private Call getCall() { 2191344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal if (mOriginalConnection != null) { 2201344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal return mOriginalConnection.getCall(); 2211344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 2221344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal return null; 2231344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 2241344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal 2251344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal SipPhone getPhone() { 2261344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal Call call = getCall(); 2271344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal if (call != null) { 2281344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal return (SipPhone) call.getPhone(); 2291344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 2301344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal return null; 2311344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 2321344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal 2331344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal private boolean isValidRingingCall() { 2341344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal Call call = getCall(); 2351344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal return call != null && call.getState().isRinging() && 2361344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal call.getEarliestConnection() == mOriginalConnection; 2371344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 2381344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal 23922d32b2b81bba31b6ebd93753a5c1ec39e911981Sailesh Nepal private void updateState(boolean force) { 2401344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal if (mOriginalConnection == null) { 2411344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal return; 2421344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 2431344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal 2441344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal Call.State newState = mOriginalConnection.getState(); 2451344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal if (VERBOSE) log("updateState, " + mOriginalConnectionState + " -> " + newState); 24622d32b2b81bba31b6ebd93753a5c1ec39e911981Sailesh Nepal if (force || mOriginalConnectionState != newState) { 2471344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal mOriginalConnectionState = newState; 2481344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal switch (newState) { 2491344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal case IDLE: 2501344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal break; 2511344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal case ACTIVE: 2521344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal setActive(); 2531344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal break; 2541344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal case HOLDING: 2551344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal setOnHold(); 2561344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal break; 2571344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal case DIALING: 2581344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal case ALERTING: 2591344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal setDialing(); 260a314b4f398ec4a0f1540c9e437bf2d7f99502b6aAnthony Lee // For SIP calls, we need to ask the framework to play the ringback for us. 26114bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee setRingbackRequested(true); 2621344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal break; 2631344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal case INCOMING: 2641344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal case WAITING: 2651344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal setRinging(); 2661344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal break; 2671344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal case DISCONNECTED: 268aef7a4bc4f85149de427d7506ebe97753b2ca6c2Andrew Lee setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause( 269aef7a4bc4f85149de427d7506ebe97753b2ca6c2Andrew Lee mOriginalConnection.getDisconnectCause())); 2701344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal close(); 2711344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal break; 2721344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal case DISCONNECTING: 2731344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal break; 2741344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 27522d32b2b81bba31b6ebd93753a5c1ec39e911981Sailesh Nepal updateCallCapabilities(force); 2761344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 2771344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 2781344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal 2791344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal private int buildCallCapabilities() { 2803cc8121590b5b05af65a9aeaa8948834e4983adcIhab Awad int capabilities = CAPABILITY_MUTE | CAPABILITY_SUPPORT_HOLD; 28176f3b4ec8d9bcb8926db1b3e4fb2d1e969b09fbbIhab Awad if (getState() == STATE_ACTIVE || getState() == STATE_HOLDING) { 2823cc8121590b5b05af65a9aeaa8948834e4983adcIhab Awad capabilities |= CAPABILITY_HOLD; 2831344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 2841344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal return capabilities; 2851344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 2861344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal 28722d32b2b81bba31b6ebd93753a5c1ec39e911981Sailesh Nepal void updateCallCapabilities(boolean force) { 2881344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal int newCallCapabilities = buildCallCapabilities(); 2893cc8121590b5b05af65a9aeaa8948834e4983adcIhab Awad if (force || getConnectionCapabilities() != newCallCapabilities) { 2903cc8121590b5b05af65a9aeaa8948834e4983adcIhab Awad setConnectionCapabilities(newCallCapabilities); 2911344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 2921344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 2931344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal 2941344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal void onAddedToCallService() { 2951344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal if (VERBOSE) log("onAddedToCallService"); 29622d32b2b81bba31b6ebd93753a5c1ec39e911981Sailesh Nepal updateState(true); 29722d32b2b81bba31b6ebd93753a5c1ec39e911981Sailesh Nepal updateCallCapabilities(true); 2981344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal setAudioModeIsVoip(true); 2992093a451b17c26f4341e9565b65dcaa0e20bbd7dSailesh Nepal if (mOriginalConnection != null) { 3002093a451b17c26f4341e9565b65dcaa0e20bbd7dSailesh Nepal setCallerDisplayName(mOriginalConnection.getCnapName(), 3012093a451b17c26f4341e9565b65dcaa0e20bbd7dSailesh Nepal mOriginalConnection.getCnapNamePresentation()); 3022093a451b17c26f4341e9565b65dcaa0e20bbd7dSailesh Nepal } 3031344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 3041344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal 3054ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn /** 3064ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn * Updates the handle on this connection based on the original connection. 3074ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn */ 30814bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee private void updateAddress() { 3094ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn if (mOriginalConnection != null) { 31014bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee Uri address = getAddressFromNumber(mOriginalConnection.getAddress()); 3114ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn int presentation = mOriginalConnection.getNumberPresentation(); 31214bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee if (!Objects.equals(address, getAddress()) || 31314bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee presentation != getAddressPresentation()) { 31414bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee com.android.services.telephony.Log.v(this, "updateAddress, address changed"); 31514bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee setAddress(address, presentation); 3164ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn } 3174ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn 3184ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn String name = mOriginalConnection.getCnapName(); 3194ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn int namePresentation = mOriginalConnection.getCnapNamePresentation(); 3204ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn if (!Objects.equals(name, getCallerDisplayName()) || 3214ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn namePresentation != getCallerDisplayNamePresentation()) { 3224ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn com.android.services.telephony.Log 32314bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee .v(this, "updateAddress, caller display name changed"); 3244ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn setCallerDisplayName(name, namePresentation); 3254ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn } 3264ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn } 3274ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn } 3284ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn 3297877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu private void setTechnologyTypeExtra() { 3307877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu int phoneType = PhoneConstants.PHONE_TYPE_SIP; 3317877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu if (getExtras() == null) { 3327877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu Bundle b = new Bundle(); 3337877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu b.putInt(TelecomManager.EXTRA_CALL_TECHNOLOGY_TYPE, phoneType); 3347877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu setExtras(b); 3357877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu } else { 3367877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu getExtras().putInt(TelecomManager.EXTRA_CALL_TECHNOLOGY_TYPE, phoneType); 3377877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu } 3387877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu } 3397877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu 3404ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn /** 34114bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee * Determines the address for an incoming number. 3424ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn * 34314bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee * @param number The incoming number. 3444ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn * @return The Uri representing the number. 3454ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn */ 34614bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee private static Uri getAddressFromNumber(String number) { 3474ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn // Address can be null for blocked calls. 34814bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee if (number == null) { 34914bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee number = ""; 3504ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn } 35114bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee return Uri.fromParts(PhoneAccount.SCHEME_SIP, number, null); 3524ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn } 3534ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn 3541344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal private void close() { 3551344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal if (getPhone() != null) { 3561344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal getPhone().unregisterForPreciseCallStateChanged(mHandler); 3571344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 3581344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal mOriginalConnection = null; 3590d5710d9bfdb36d5d0a7be4eaf3f39ae3fb30bc5Evan Charlton destroy(); 3601344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal } 3611344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal 362788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal private static void log(String msg) { 363788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal Log.d(SipUtil.LOG_TAG, PREFIX + msg); 364788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal } 365788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal} 366