SipConnection.java revision 3ba1419ade788f717dc2beb9667224dc9ed2e317
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;
201344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepalimport android.os.Handler;
211344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepalimport android.os.Message;
224d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunnimport android.telecom.AudioState;
234d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunnimport android.telecom.Connection;
244d45d1cf58a2003378fd35912d6d73a00001bf06Tyler Gunnimport android.telecom.PhoneAccount;
25788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepalimport android.util.Log;
26788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
271344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepalimport com.android.internal.telephony.Call;
281344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepalimport com.android.internal.telephony.CallStateException;
291344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepalimport com.android.internal.telephony.sip.SipPhone;
30aef7a4bc4f85149de427d7506ebe97753b2ca6c2Andrew Leeimport com.android.services.telephony.DisconnectCauseUtil;
311344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
324ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunnimport java.util.Objects;
33788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
341344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepalfinal class SipConnection extends Connection {
35788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    private static final String PREFIX = "[SipConnection] ";
366556a09daab949853c384b385bc7618a6c75d9ddSantos Cordon    private static final boolean VERBOSE = false; /* STOP SHIP if true */
37788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
381344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    private static final int MSG_PRECISE_CALL_STATE_CHANGED = 1;
391344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
401344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    private final Handler mHandler = new Handler() {
411344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        @Override
421344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        public void handleMessage(Message msg) {
431344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            switch (msg.what) {
441344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                case MSG_PRECISE_CALL_STATE_CHANGED:
4522d32b2b81bba31b6ebd93753a5c1ec39e911981Sailesh Nepal                    updateState(false);
461344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    break;
471344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            }
481344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
491344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    };
501344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
511344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    private com.android.internal.telephony.Connection mOriginalConnection;
521344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    private Call.State mOriginalConnectionState = Call.State.IDLE;
53788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
54aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton    SipConnection() {
55aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton        if (VERBOSE) log("new SipConnection");
56aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton        setInitializing();
57aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton    }
58aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton
59aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton    void initialize(com.android.internal.telephony.Connection connection) {
60aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton        if (VERBOSE) log("init SipConnection, connection: " + connection);
611344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        mOriginalConnection = connection;
621344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        if (getPhone() != null) {
631344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            getPhone().registerForPreciseCallStateChanged(mHandler, MSG_PRECISE_CALL_STATE_CHANGED,
641344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    null);
651344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
6614bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee        updateAddress();
67aaf3850172bde1fec1a4558653c0edd31e3fa71fEvan Charlton        setInitialized();
68788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
69788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
70788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
71c927106af6c47ad1f302e13fa8626be83bb46f14Nancy Chen    public void onAudioStateChanged(AudioState state) {
72c927106af6c47ad1f302e13fa8626be83bb46f14Nancy Chen        if (VERBOSE) log("onAudioStateChanged: " + state);
731344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        if (getPhone() != null) {
741344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            getPhone().setEchoSuppressionEnabled();
751344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
76788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
77788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
78788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
79c927106af6c47ad1f302e13fa8626be83bb46f14Nancy Chen    public void onStateChanged(int state) {
80c927106af6c47ad1f302e13fa8626be83bb46f14Nancy Chen        if (VERBOSE) log("onStateChanged, state: " + Connection.stateToString(state));
81788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
82788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
83788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
84ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onPlayDtmfTone(char c) {
85788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        if (VERBOSE) log("onPlayDtmfTone");
861344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        if (getPhone() != null) {
871344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            getPhone().startDtmf(c);
881344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
89788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
90788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
91788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
92ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onStopDtmfTone() {
93788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        if (VERBOSE) log("onStopDtmfTone");
941344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        if (getPhone() != null) {
951344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            getPhone().stopDtmf();
961344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
97788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
98788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
99788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
100ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onDisconnect() {
101788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        if (VERBOSE) log("onDisconnect");
1021344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        try {
1031344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            if (getCall() != null && !getCall().isMultiparty()) {
1041344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                getCall().hangup();
1051344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            } else if (mOriginalConnection != null) {
1061344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                mOriginalConnection.hangup();
1071344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            }
1081344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        } catch (CallStateException e) {
1091344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            log("onDisconnect, exception: " + e);
1101344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
111788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
112788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
113788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
114ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onSeparate() {
115788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        if (VERBOSE) log("onSeparate");
1161344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        try {
1171344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            if (mOriginalConnection != null) {
1181344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                mOriginalConnection.separate();
1191344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            }
1201344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        } catch (CallStateException e) {
1211344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            log("onSeparate, exception: " + e);
1221344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
123788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
124788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
125788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
126ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onAbort() {
127788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        if (VERBOSE) log("onAbort");
1281344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        onDisconnect();
129788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
130788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
131788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
132ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onHold() {
133788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        if (VERBOSE) log("onHold");
1341344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        try {
1352c304ad93f8e74e4a14374d6e00a50cd3497d592Kosuge Yuji            if (getPhone() != null && getState() == STATE_ACTIVE
1362c304ad93f8e74e4a14374d6e00a50cd3497d592Kosuge Yuji                    && getPhone().getRingingCall().getState() != Call.State.WAITING) {
1373ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                // Double check with the internal state since a discrepancy in states could mean
1383ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                // that the transactions is already in progress from a previous request.
1393ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                if (mOriginalConnection != null &&
1403ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                        mOriginalConnection.getState() == Call.State.ACTIVE) {
1413ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                    getPhone().switchHoldingAndActive();
1423ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                } else {
1433ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                    log("skipping switch from onHold due to internal state:");
1443ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                }
1451344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            }
1461344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        } catch (CallStateException e) {
1471344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            log("onHold, exception: " + e);
1481344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
149788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
150788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
151788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
152ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onUnhold() {
153788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        if (VERBOSE) log("onUnhold");
1541344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        try {
155caf84dca8bd90016d910198f1b178ac03e82dd07Roshan Pius            if (getPhone() != null && getState() == STATE_HOLDING &&
156caf84dca8bd90016d910198f1b178ac03e82dd07Roshan Pius                    getPhone().getForegroundCall().getState() != Call.State.DIALING) {
1573ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                // Double check with the internal state since a discrepancy in states could mean
1583ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                // that the transaction is already in progress from a previous request.
1593ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                if (mOriginalConnection != null &&
1603ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                        mOriginalConnection.getState() == Call.State.HOLDING) {
1613ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                    getPhone().switchHoldingAndActive();
1623ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                } else {
1633ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                    log("skipping switch from onUnHold due to internal state.");
1643ba1419ade788f717dc2beb9667224dc9ed2e317Santos Cordon                }
1651344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            }
1661344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        } catch (CallStateException e) {
1671344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            log("onUnhold, exception: " + e);
1681344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
169788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
170788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
171788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
172ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onAnswer(int videoState) {
173788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        if (VERBOSE) log("onAnswer");
1741344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        try {
1751344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            if (isValidRingingCall() && getPhone() != null) {
1760bbcc4f2f0218f451a680b98a62c374bba877c3bAndrew Lee                getPhone().acceptCall(videoState);
1771344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            }
1781344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        } catch (CallStateException e) {
1791344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            log("onAnswer, exception: " + e);
1801344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
181788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
182788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
183788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
184ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onReject() {
185788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        if (VERBOSE) log("onReject");
1861344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        try {
1871344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            if (isValidRingingCall() && getPhone() != null) {
1881344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                getPhone().rejectCall();
1891344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            }
1901344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        } catch (CallStateException e) {
1911344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            log("onReject, exception: " + e);
1921344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
193788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
194788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
195788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    @Override
196ab777070da7e83983739414f1222177c6aeebe1aSantos Cordon    public void onPostDialContinue(boolean proceed) {
197788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        if (VERBOSE) log("onPostDialContinue, proceed: " + proceed);
1981344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        // SIP doesn't have post dial support.
199788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
200788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal
2011344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    private Call getCall() {
2021344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        if (mOriginalConnection != null) {
2031344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            return mOriginalConnection.getCall();
2041344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
2051344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        return null;
2061344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    }
2071344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
2081344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    SipPhone getPhone() {
2091344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        Call call = getCall();
2101344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        if (call != null) {
2111344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            return (SipPhone) call.getPhone();
2121344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
2131344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        return null;
2141344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    }
2151344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
2161344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    private boolean isValidRingingCall() {
2171344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        Call call = getCall();
2181344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        return call != null && call.getState().isRinging() &&
2191344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                call.getEarliestConnection() == mOriginalConnection;
2201344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    }
2211344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
22222d32b2b81bba31b6ebd93753a5c1ec39e911981Sailesh Nepal    private void updateState(boolean force) {
2231344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        if (mOriginalConnection == null) {
2241344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            return;
2251344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
2261344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
2271344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        Call.State newState = mOriginalConnection.getState();
2281344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        if (VERBOSE) log("updateState, " + mOriginalConnectionState + " -> " + newState);
22922d32b2b81bba31b6ebd93753a5c1ec39e911981Sailesh Nepal        if (force || mOriginalConnectionState != newState) {
2301344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            mOriginalConnectionState = newState;
2311344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            switch (newState) {
2321344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                case IDLE:
2331344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    break;
2341344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                case ACTIVE:
2351344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    setActive();
2361344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    break;
2371344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                case HOLDING:
2381344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    setOnHold();
2391344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    break;
2401344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                case DIALING:
2411344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                case ALERTING:
2421344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    setDialing();
243a314b4f398ec4a0f1540c9e437bf2d7f99502b6aAnthony Lee                    // For SIP calls, we need to ask the framework to play the ringback for us.
24414bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee                    setRingbackRequested(true);
2451344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    break;
2461344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                case INCOMING:
2471344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                case WAITING:
2481344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    setRinging();
2491344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    break;
2501344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                case DISCONNECTED:
251aef7a4bc4f85149de427d7506ebe97753b2ca6c2Andrew Lee                    setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(
252aef7a4bc4f85149de427d7506ebe97753b2ca6c2Andrew Lee                            mOriginalConnection.getDisconnectCause()));
2531344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    close();
2541344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    break;
2551344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                case DISCONNECTING:
2561344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal                    break;
2571344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            }
25822d32b2b81bba31b6ebd93753a5c1ec39e911981Sailesh Nepal            updateCallCapabilities(force);
2591344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
2601344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    }
2611344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
2621344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    private int buildCallCapabilities() {
2633cc8121590b5b05af65a9aeaa8948834e4983adcIhab Awad        int capabilities = CAPABILITY_MUTE | CAPABILITY_SUPPORT_HOLD;
26476f3b4ec8d9bcb8926db1b3e4fb2d1e969b09fbbIhab Awad        if (getState() == STATE_ACTIVE || getState() == STATE_HOLDING) {
2653cc8121590b5b05af65a9aeaa8948834e4983adcIhab Awad            capabilities |= CAPABILITY_HOLD;
2661344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
2671344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        return capabilities;
2681344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    }
2691344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
27022d32b2b81bba31b6ebd93753a5c1ec39e911981Sailesh Nepal    void updateCallCapabilities(boolean force) {
2711344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        int newCallCapabilities = buildCallCapabilities();
2723cc8121590b5b05af65a9aeaa8948834e4983adcIhab Awad        if (force || getConnectionCapabilities() != newCallCapabilities) {
2733cc8121590b5b05af65a9aeaa8948834e4983adcIhab Awad            setConnectionCapabilities(newCallCapabilities);
2741344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
2751344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    }
2761344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
2771344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    void onAddedToCallService() {
2781344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        if (VERBOSE) log("onAddedToCallService");
27922d32b2b81bba31b6ebd93753a5c1ec39e911981Sailesh Nepal        updateState(true);
28022d32b2b81bba31b6ebd93753a5c1ec39e911981Sailesh Nepal        updateCallCapabilities(true);
2811344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        setAudioModeIsVoip(true);
2822093a451b17c26f4341e9565b65dcaa0e20bbd7dSailesh Nepal        if (mOriginalConnection != null) {
2832093a451b17c26f4341e9565b65dcaa0e20bbd7dSailesh Nepal            setCallerDisplayName(mOriginalConnection.getCnapName(),
2842093a451b17c26f4341e9565b65dcaa0e20bbd7dSailesh Nepal                    mOriginalConnection.getCnapNamePresentation());
2852093a451b17c26f4341e9565b65dcaa0e20bbd7dSailesh Nepal        }
2861344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    }
2871344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
2884ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn    /**
2894ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn     * Updates the handle on this connection based on the original connection.
2904ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn     */
29114bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee    private void updateAddress() {
2924ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn        if (mOriginalConnection != null) {
29314bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee            Uri address = getAddressFromNumber(mOriginalConnection.getAddress());
2944ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn            int presentation = mOriginalConnection.getNumberPresentation();
29514bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee            if (!Objects.equals(address, getAddress()) ||
29614bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee                    presentation != getAddressPresentation()) {
29714bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee                com.android.services.telephony.Log.v(this, "updateAddress, address changed");
29814bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee                setAddress(address, presentation);
2994ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn            }
3004ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn
3014ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn            String name = mOriginalConnection.getCnapName();
3024ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn            int namePresentation = mOriginalConnection.getCnapNamePresentation();
3034ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn            if (!Objects.equals(name, getCallerDisplayName()) ||
3044ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn                    namePresentation != getCallerDisplayNamePresentation()) {
3054ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn                com.android.services.telephony.Log
30614bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee                        .v(this, "updateAddress, caller display name changed");
3074ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn                setCallerDisplayName(name, namePresentation);
3084ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn            }
3094ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn        }
3104ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn    }
3114ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn
3124ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn    /**
31314bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee     * Determines the address for an incoming number.
3144ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn     *
31514bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee     * @param number The incoming number.
3164ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn     * @return The Uri representing the number.
3174ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn     */
31814bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee    private static Uri getAddressFromNumber(String number) {
3194ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn        // Address can be null for blocked calls.
32014bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee        if (number == null) {
32114bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee            number = "";
3224ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn        }
32314bf354aab420fcd099cd0209238d7b92dad6f1dAndrew Lee        return Uri.fromParts(PhoneAccount.SCHEME_SIP, number, null);
3244ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn    }
3254ddd0efe67e93798d98c86b073d6cd0b1343f840Tyler Gunn
3261344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    private void close() {
3271344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        if (getPhone() != null) {
3281344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal            getPhone().unregisterForPreciseCallStateChanged(mHandler);
3291344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        }
3301344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal        mOriginalConnection = null;
3310d5710d9bfdb36d5d0a7be4eaf3f39ae3fb30bc5Evan Charlton        destroy();
3321344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal    }
3331344f67ea331f9a485f54c4b5e26d62a5cfad3fbSailesh Nepal
334788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    private static void log(String msg) {
335788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal        Log.d(SipUtil.LOG_TAG, PREFIX + msg);
336788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal    }
337788959e2d798da2d8a34cf89779421966d200f3dSailesh Nepal}
338