SipConnection.java revision 7877c7255268c34a71c7d1b4055afabb8fcba04c
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;
27788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepalimport android.util.Log;
28788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
291344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepalimport com.android.internal.telephony.Call;
301344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepalimport com.android.internal.telephony.CallStateException;
317877c7255268c34a71c7d1b4055afabb8fcba04cHall Liuimport com.android.internal.telephony.PhoneConstants;
321344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepalimport com.android.internal.telephony.sip.SipPhone;
33aef7a4bc4f85149de427d7506ebe97753b2ca6c2Andrew Leeimport com.android.services.telephony.DisconnectCauseUtil;
341344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
354ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunnimport java.util.Objects;
36788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
371344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepalfinal class SipConnection extends Connection {
38788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    private static final String PREFIX = "[SipConnection] ";
396556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon    private static final boolean VERBOSE = false; /* STOP SHIP if true */
40788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
411344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    private static final int MSG_PRECISE_CALL_STATE_CHANGED = 1;
421344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
431344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    private final Handler mHandler = new Handler() {
441344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        @Override
451344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        public void handleMessage(Message msg) {
461344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            switch (msg.what) {
471344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                case MSG_PRECISE_CALL_STATE_CHANGED:
4822d32b2b81bba31b6ebd93753a5c1ec39e911981Sailesh Nepal                    updateState(false);
491344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    break;
501344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            }
511344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
521344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    };
531344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
541344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    private com.android.internal.telephony.Connection mOriginalConnection;
551344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    private Call.State mOriginalConnectionState = Call.State.IDLE;
56788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
57aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton    SipConnection() {
58aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton        if (VERBOSE) log("new SipConnection");
59aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton        setInitializing();
60aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton    }
61aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton
62aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton    void initialize(com.android.internal.telephony.Connection connection) {
63aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton        if (VERBOSE) log("init SipConnection, connection: " + connection);
641344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        mOriginalConnection = connection;
651344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        if (getPhone() != null) {
661344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            getPhone().registerForPreciseCallStateChanged(mHandler, MSG_PRECISE_CALL_STATE_CHANGED,
671344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    null);
681344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
6914bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee        updateAddress();
707877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu        setTechnologyTypeExtra();
71aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton        setInitialized();
72788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
73788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
74788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
75c927106af6c47ad1f302e13fa8626be83bb46f14Nancy Chen    public void onAudioStateChanged(AudioState state) {
76c927106af6c47ad1f302e13fa8626be83bb46f14Nancy Chen        if (VERBOSE) log("onAudioStateChanged: " + state);
771344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        if (getPhone() != null) {
781344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            getPhone().setEchoSuppressionEnabled();
791344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
80788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
81788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
82788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
83c927106af6c47ad1f302e13fa8626be83bb46f14Nancy Chen    public void onStateChanged(int state) {
84c927106af6c47ad1f302e13fa8626be83bb46f14Nancy Chen        if (VERBOSE) log("onStateChanged, state: " + Connection.stateToString(state));
85788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
86788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
87788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
88ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onPlayDtmfTone(char c) {
89788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        if (VERBOSE) log("onPlayDtmfTone");
901344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        if (getPhone() != null) {
911344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            getPhone().startDtmf(c);
921344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
93788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
94788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
95788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
96ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onStopDtmfTone() {
97788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        if (VERBOSE) log("onStopDtmfTone");
981344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        if (getPhone() != null) {
991344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            getPhone().stopDtmf();
1001344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
101788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
102788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
103788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
104ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onDisconnect() {
105788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        if (VERBOSE) log("onDisconnect");
1061344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        try {
1071344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            if (getCall() != null && !getCall().isMultiparty()) {
1081344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                getCall().hangup();
1091344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            } else if (mOriginalConnection != null) {
1101344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                mOriginalConnection.hangup();
1111344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            }
1121344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        } catch (CallStateException e) {
1131344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            log("onDisconnect, exception: " + e);
1141344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
115788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
116788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
117788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
118ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onSeparate() {
119788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        if (VERBOSE) log("onSeparate");
1201344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        try {
1211344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            if (mOriginalConnection != null) {
1221344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                mOriginalConnection.separate();
1231344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            }
1241344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        } catch (CallStateException e) {
1251344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            log("onSeparate, exception: " + e);
1261344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
127788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
128788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
129788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
130ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onAbort() {
131788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        if (VERBOSE) log("onAbort");
1321344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        onDisconnect();
133788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
134788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
135788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
136ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onHold() {
137788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        if (VERBOSE) log("onHold");
1381344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        try {
1392c304ad93f8e74e4a14374d6e00a50cd3497d592Kosuge Yuji            if (getPhone() != null && getState() == STATE_ACTIVE
1402c304ad93f8e74e4a14374d6e00a50cd3497d592Kosuge Yuji                    && getPhone().getRingingCall().getState() != Call.State.WAITING) {
1413ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                // Double check with the internal state since a discrepancy in states could mean
1423ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                // that the transactions is already in progress from a previous request.
1433ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                if (mOriginalConnection != null &&
1443ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                        mOriginalConnection.getState() == Call.State.ACTIVE) {
1453ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                    getPhone().switchHoldingAndActive();
1463ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                } else {
1473ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                    log("skipping switch from onHold due to internal state:");
1483ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                }
1491344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            }
1501344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        } catch (CallStateException e) {
1511344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            log("onHold, exception: " + e);
1521344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
153788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
154788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
155788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
156ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onUnhold() {
157788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        if (VERBOSE) log("onUnhold");
1581344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        try {
159caf84dca8bd90016d910198f1b178ac03e82dd07Roshan Pius            if (getPhone() != null && getState() == STATE_HOLDING &&
160caf84dca8bd90016d910198f1b178ac03e82dd07Roshan Pius                    getPhone().getForegroundCall().getState() != Call.State.DIALING) {
1613ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                // Double check with the internal state since a discrepancy in states could mean
1623ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                // that the transaction is already in progress from a previous request.
1633ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                if (mOriginalConnection != null &&
1643ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                        mOriginalConnection.getState() == Call.State.HOLDING) {
1653ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                    getPhone().switchHoldingAndActive();
1663ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                } else {
1673ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                    log("skipping switch from onUnHold due to internal state.");
1683ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                }
1691344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            }
1701344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        } catch (CallStateException e) {
1711344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            log("onUnhold, exception: " + e);
1721344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
173788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
174788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
175788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
176ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onAnswer(int videoState) {
177788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        if (VERBOSE) log("onAnswer");
1781344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        try {
1791344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            if (isValidRingingCall() && getPhone() != null) {
1800bbcc4f2f0218f451a680b98a62c374bba877c3bAndrew Lee                getPhone().acceptCall(videoState);
1811344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            }
1821344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        } catch (CallStateException e) {
1831344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            log("onAnswer, exception: " + e);
1841344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
185788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
186788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
187788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
188ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onReject() {
189788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        if (VERBOSE) log("onReject");
1901344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        try {
1911344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            if (isValidRingingCall() && getPhone() != null) {
1921344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                getPhone().rejectCall();
1931344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            }
1941344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        } catch (CallStateException e) {
1951344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            log("onReject, exception: " + e);
1961344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
197788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
198788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
199788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
200ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onPostDialContinue(boolean proceed) {
201788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        if (VERBOSE) log("onPostDialContinue, proceed: " + proceed);
2021344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        // SIP doesn't have post dial support.
203788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
204788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
2051344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    private Call getCall() {
2061344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        if (mOriginalConnection != null) {
2071344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            return mOriginalConnection.getCall();
2081344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
2091344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        return null;
2101344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    }
2111344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
2121344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    SipPhone getPhone() {
2131344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        Call call = getCall();
2141344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        if (call != null) {
2151344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            return (SipPhone) call.getPhone();
2161344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
2171344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        return null;
2181344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    }
2191344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
2201344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    private boolean isValidRingingCall() {
2211344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        Call call = getCall();
2221344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        return call != null && call.getState().isRinging() &&
2231344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                call.getEarliestConnection() == mOriginalConnection;
2241344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    }
2251344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
22622d32b2b81bba31b6ebd93753a5c1ec39e911981Sailesh Nepal    private void updateState(boolean force) {
2271344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        if (mOriginalConnection == null) {
2281344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            return;
2291344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
2301344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
2311344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        Call.State newState = mOriginalConnection.getState();
2321344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        if (VERBOSE) log("updateState, " + mOriginalConnectionState + " -> " + newState);
23322d32b2b81bba31b6ebd93753a5c1ec39e911981Sailesh Nepal        if (force || mOriginalConnectionState != newState) {
2341344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            mOriginalConnectionState = newState;
2351344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            switch (newState) {
2361344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                case IDLE:
2371344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    break;
2381344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                case ACTIVE:
2391344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    setActive();
2401344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    break;
2411344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                case HOLDING:
2421344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    setOnHold();
2431344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    break;
2441344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                case DIALING:
2451344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                case ALERTING:
2461344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    setDialing();
247a314b4f398ec4a0f1540c9e437bf2d7f99502b6aAnthony Lee                    // For SIP calls, we need to ask the framework to play the ringback for us.
24814bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee                    setRingbackRequested(true);
2491344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    break;
2501344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                case INCOMING:
2511344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                case WAITING:
2521344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    setRinging();
2531344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    break;
2541344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                case DISCONNECTED:
255aef7a4bc4f85149de427d7506ebe97753b2ca6c2Andrew Lee                    setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(
256aef7a4bc4f85149de427d7506ebe97753b2ca6c2Andrew Lee                            mOriginalConnection.getDisconnectCause()));
2571344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    close();
2581344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    break;
2591344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                case DISCONNECTING:
2601344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    break;
2611344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            }
26222d32b2b81bba31b6ebd93753a5c1ec39e911981Sailesh Nepal            updateCallCapabilities(force);
2631344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
2641344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    }
2651344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
2661344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    private int buildCallCapabilities() {
2673cc8121590b5b05af65a9aeaa8948834e4983adcIhab Awad        int capabilities = CAPABILITY_MUTE | CAPABILITY_SUPPORT_HOLD;
26876f3b4ec8d9bcb8926db1b3e4fb2d1e969b09fbbIhab Awad        if (getState() == STATE_ACTIVE || getState() == STATE_HOLDING) {
2693cc8121590b5b05af65a9aeaa8948834e4983adcIhab Awad            capabilities |= CAPABILITY_HOLD;
2701344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
2711344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        return capabilities;
2721344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    }
2731344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
27422d32b2b81bba31b6ebd93753a5c1ec39e911981Sailesh Nepal    void updateCallCapabilities(boolean force) {
2751344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        int newCallCapabilities = buildCallCapabilities();
2763cc8121590b5b05af65a9aeaa8948834e4983adcIhab Awad        if (force || getConnectionCapabilities() != newCallCapabilities) {
2773cc8121590b5b05af65a9aeaa8948834e4983adcIhab Awad            setConnectionCapabilities(newCallCapabilities);
2781344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
2791344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    }
2801344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
2811344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    void onAddedToCallService() {
2821344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        if (VERBOSE) log("onAddedToCallService");
28322d32b2b81bba31b6ebd93753a5c1ec39e911981Sailesh Nepal        updateState(true);
28422d32b2b81bba31b6ebd93753a5c1ec39e911981Sailesh Nepal        updateCallCapabilities(true);
2851344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        setAudioModeIsVoip(true);
2862093a451b17c26f4341e9565b65dcaa0e20bbd7dSailesh Nepal        if (mOriginalConnection != null) {
2872093a451b17c26f4341e9565b65dcaa0e20bbd7dSailesh Nepal            setCallerDisplayName(mOriginalConnection.getCnapName(),
2882093a451b17c26f4341e9565b65dcaa0e20bbd7dSailesh Nepal                    mOriginalConnection.getCnapNamePresentation());
2892093a451b17c26f4341e9565b65dcaa0e20bbd7dSailesh Nepal        }
2901344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    }
2911344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
2924ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn    /**
2934ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn     * Updates the handle on this connection based on the original connection.
2944ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn     */
29514bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee    private void updateAddress() {
2964ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn        if (mOriginalConnection != null) {
29714bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee            Uri address = getAddressFromNumber(mOriginalConnection.getAddress());
2984ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn            int presentation = mOriginalConnection.getNumberPresentation();
29914bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee            if (!Objects.equals(address, getAddress()) ||
30014bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee                    presentation != getAddressPresentation()) {
30114bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee                com.android.services.telephony.Log.v(this, "updateAddress, address changed");
30214bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee                setAddress(address, presentation);
3034ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn            }
3044ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn
3054ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn            String name = mOriginalConnection.getCnapName();
3064ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn            int namePresentation = mOriginalConnection.getCnapNamePresentation();
3074ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn            if (!Objects.equals(name, getCallerDisplayName()) ||
3084ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn                    namePresentation != getCallerDisplayNamePresentation()) {
3094ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn                com.android.services.telephony.Log
31014bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee                        .v(this, "updateAddress, caller display name changed");
3114ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn                setCallerDisplayName(name, namePresentation);
3124ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn            }
3134ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn        }
3144ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn    }
3154ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn
3167877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu    private void setTechnologyTypeExtra() {
3177877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu        int phoneType = PhoneConstants.PHONE_TYPE_SIP;
3187877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu        if (getExtras() == null) {
3197877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu            Bundle b = new Bundle();
3207877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu            b.putInt(TelecomManager.EXTRA_CALL_TECHNOLOGY_TYPE, phoneType);
3217877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu            setExtras(b);
3227877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu        } else {
3237877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu            getExtras().putInt(TelecomManager.EXTRA_CALL_TECHNOLOGY_TYPE, phoneType);
3247877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu        }
3257877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu    }
3267877c7255268c34a71c7d1b4055afabb8fcba04cHall Liu
3274ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn    /**
32814bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee     * Determines the address for an incoming number.
3294ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn     *
33014bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee     * @param number The incoming number.
3314ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn     * @return The Uri representing the number.
3324ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn     */
33314bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee    private static Uri getAddressFromNumber(String number) {
3344ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn        // Address can be null for blocked calls.
33514bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee        if (number == null) {
33614bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee            number = "";
3374ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn        }
33814bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee        return Uri.fromParts(PhoneAccount.SCHEME_SIP, number, null);
3394ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn    }
3404ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn
3411344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    private void close() {
3421344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        if (getPhone() != null) {
3431344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            getPhone().unregisterForPreciseCallStateChanged(mHandler);
3441344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
3451344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        mOriginalConnection = null;
3460d5710d9bfdb36d5d0a7be4eaf3f39ae3fb30bc5Evan Charlton        destroy();
3471344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    }
3481344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
349788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    private static void log(String msg) {
350788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        Log.d(SipUtil.LOG_TAG, PREFIX + msg);
351788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
352788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal}
353