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
1961952e69d543ddc7bffdefb89cb512e22b00bf49Uma Maheswari Ramalingamimport android.telecom.ConferenceParticipant;
20a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.Rlog;
21a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport android.telephony.DisconnectCause;
22707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunnimport android.util.Log;
23a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
240d4f1fe3137cc4a76fc2bb0dac80c68220e53550Tyler Gunnimport com.android.internal.annotations.VisibleForTesting;
25a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.Call;
26a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.CallStateException;
27a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.Connection;
28a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.internal.telephony.Phone;
29a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.ims.ImsCall;
30a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.ims.ImsException;
31a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport com.android.ims.ImsStreamMediaProfile;
32a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
33a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleimport java.util.List;
34a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
35a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville/**
36a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * {@hide}
37a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville */
385d0d72d9b7dc34c93303f6732541bbb74fed53daEtan Cohenpublic class ImsPhoneCall extends Call {
39a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private static final String LOG_TAG = "ImsPhoneCall";
40a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
41707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    // This flag is meant to be used as a debugging tool to quickly see all logs
42707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    // regardless of the actual log level set on this component.
43707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    private static final boolean FORCE_DEBUG = false; /* STOPSHIP if true */
44707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    private static final boolean DBG = FORCE_DEBUG || Rlog.isLoggable(LOG_TAG, Log.DEBUG);
45707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    private static final boolean VDBG = FORCE_DEBUG || Rlog.isLoggable(LOG_TAG, Log.VERBOSE);
46707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn
47707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    /*************************** Instance Variables **************************/
48707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    public static final String CONTEXT_UNKNOWN = "UK";
49707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    public static final String CONTEXT_RINGING = "RG";
50707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    public static final String CONTEXT_FOREGROUND = "FG";
51707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    public static final String CONTEXT_BACKGROUND = "BG";
52707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    public static final String CONTEXT_HANDOVER = "HO";
53707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn
54a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /*package*/ ImsPhoneCallTracker mOwner;
55a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
56a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private boolean mRingbackTonePlayed = false;
57a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
58707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    // Determines what type of ImsPhoneCall this is.  ImsPhoneCallTracker uses instances of
59707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    // ImsPhoneCall to for fg, bg, etc calls.  This is used as a convenience for logging so that it
60707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    // can be made clear whether a call being logged is the foreground, background, etc.
61707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    private final String mCallContext;
62707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn
63a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /****************************** Constructors *****************************/
64a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /*package*/
65a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    ImsPhoneCall() {
66707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        mCallContext = CONTEXT_UNKNOWN;
67a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
68a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
69f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxu    public ImsPhoneCall(ImsPhoneCallTracker owner, String context) {
70a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mOwner = owner;
71707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        mCallContext = context;
72a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
73a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
74a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void dispose() {
75a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        try {
76a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            mOwner.hangup(this);
77a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } catch (CallStateException ex) {
78a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            //Rlog.e(LOG_TAG, "dispose: unexpected error on hangup", ex);
79a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            //while disposing, ignore the exception and clean the connections
80a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } finally {
81a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            for(int i = 0, s = mConnections.size(); i < s; i++) {
82a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ImsPhoneConnection c = (ImsPhoneConnection) mConnections.get(i);
83a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                c.onDisconnect(DisconnectCause.LOST_SIGNAL);
84a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
85a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
86a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
87a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
88a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /************************** Overridden from Call *************************/
89a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
90a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
91a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public List<Connection>
92a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    getConnections() {
93a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mConnections;
94a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
95a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
96a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
97a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public Phone
98a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    getPhone() {
99a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mOwner.mPhone;
100a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
101a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
102a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
103a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public boolean
104a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    isMultiparty() {
1052c38178d30afd3f168c6506f0942f93c785d3d7eTyler Gunn        ImsCall imsCall = getImsCall();
1062c38178d30afd3f168c6506f0942f93c785d3d7eTyler Gunn        if (imsCall == null) {
1072c38178d30afd3f168c6506f0942f93c785d3d7eTyler Gunn            return false;
1082c38178d30afd3f168c6506f0942f93c785d3d7eTyler Gunn        }
1092c38178d30afd3f168c6506f0942f93c785d3d7eTyler Gunn
1102c38178d30afd3f168c6506f0942f93c785d3d7eTyler Gunn        return imsCall.isMultiparty();
111a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
112a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
113a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /** Please note: if this is the foreground call and a
114a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     *  background call exists, the background call will be resumed.
115a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
116a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
117a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    public void
118a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    hangup() throws CallStateException {
119a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mOwner.hangup(this);
120a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
121a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
122a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    @Override
123707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn    public String toString() {
124707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        StringBuilder sb = new StringBuilder();
125707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append("[ImsPhoneCall ");
126707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append(mCallContext);
127707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append(" state: ");
128707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append(mState.toString());
129707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append(" ");
130707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        if (mConnections.size() > 1) {
131707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            sb.append(" ERROR_MULTIPLE ");
132707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        }
133707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        for (Connection conn : mConnections) {
134707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            sb.append(conn);
135707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            sb.append(" ");
136707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        }
137707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn
138707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        sb.append("]");
139707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        return sb.toString();
140a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
141a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
14261952e69d543ddc7bffdefb89cb512e22b00bf49Uma Maheswari Ramalingam    @Override
14361952e69d543ddc7bffdefb89cb512e22b00bf49Uma Maheswari Ramalingam    public List<ConferenceParticipant> getConferenceParticipants() {
14461952e69d543ddc7bffdefb89cb512e22b00bf49Uma Maheswari Ramalingam         ImsCall call = getImsCall();
14561952e69d543ddc7bffdefb89cb512e22b00bf49Uma Maheswari Ramalingam         if (call == null) {
14661952e69d543ddc7bffdefb89cb512e22b00bf49Uma Maheswari Ramalingam             return null;
14761952e69d543ddc7bffdefb89cb512e22b00bf49Uma Maheswari Ramalingam         }
14861952e69d543ddc7bffdefb89cb512e22b00bf49Uma Maheswari Ramalingam         return call.getConferenceParticipants();
14961952e69d543ddc7bffdefb89cb512e22b00bf49Uma Maheswari Ramalingam    }
15061952e69d543ddc7bffdefb89cb512e22b00bf49Uma Maheswari Ramalingam
151a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Called from ImsPhoneConnection
152a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
153f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxu    public void attach(Connection conn) {
154707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        if (VDBG) {
155707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            Rlog.v(LOG_TAG, "attach : " + mCallContext + " conn = " + conn);
156707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        }
157a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        clearDisconnected();
158a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mConnections.add(conn);
159707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn
160707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        mOwner.logState();
161a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
162a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
163f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxu    public void attach(Connection conn, State state) {
164707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        if (VDBG) {
165707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            Rlog.v(LOG_TAG, "attach : " + mCallContext + " state = " +
166707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                    state.toString());
167707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        }
168a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        this.attach(conn);
169a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mState = state;
170a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
171a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
172f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxu    public void attachFake(Connection conn, State state) {
173a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        attach(conn, state);
174a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
175a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
176a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
177a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * Called by ImsPhoneConnection when it has disconnected
178a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
179f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxu    public boolean connectionDisconnected(ImsPhoneConnection conn) {
180a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mState != State.DISCONNECTED) {
181a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            /* If only disconnected connections remain, we are disconnected*/
182a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
183a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            boolean hasOnlyDisconnectedConnections = true;
184a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
185a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            for (int i = 0, s = mConnections.size()  ; i < s; i ++) {
186a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                if (mConnections.get(i).getState() != State.DISCONNECTED) {
187a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    hasOnlyDisconnectedConnections = false;
188a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                    break;
189a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                }
190a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
191a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
192a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (hasOnlyDisconnectedConnections) {
193a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mState = State.DISCONNECTED;
1949cf07ae65ed86b9e79aaa74b66441f0811d9cc15Tyler Gunn                if (VDBG) {
1959cf07ae65ed86b9e79aaa74b66441f0811d9cc15Tyler Gunn                    Rlog.v(LOG_TAG, "connectionDisconnected : " + mCallContext + " state = " +
1969cf07ae65ed86b9e79aaa74b66441f0811d9cc15Tyler Gunn                            mState);
1979cf07ae65ed86b9e79aaa74b66441f0811d9cc15Tyler Gunn                }
198a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                return true;
199a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
200a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
201a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
202a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return false;
203a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
204a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
205f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxu    public void detach(ImsPhoneConnection conn) {
206707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        if (VDBG) {
207707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            Rlog.v(LOG_TAG, "detach : " + mCallContext + " conn = " + conn);
208707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        }
209a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mConnections.remove(conn);
210db3aec65b5c02e3f5b28d32e4c742ba72a4b3867Andrew Lee        clearDisconnected();
211707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn
212707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        mOwner.logState();
213a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
214a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
215a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
216a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * @return true if there's no space in this call for additional
217a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * connections to be added via "conference"
218a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
219a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /*package*/ boolean
220a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    isFull() {
221a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return mConnections.size() == ImsPhoneCallTracker.MAX_CONNECTIONS_PER_CALL;
222a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
223a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
224a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    //***** Called from ImsPhoneCallTracker
225a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /**
226a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     * Called when this Call is being hung up locally (eg, user pressed "end")
227a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville     */
228a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    void
229a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    onHangupLocal() {
230a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (int i = 0, s = mConnections.size(); i < s; i++) {
231a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ImsPhoneConnection cn = (ImsPhoneConnection)mConnections.get(i);
232a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            cn.onHangupLocal();
233a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
234a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mState = State.DISCONNECTING;
2359cf07ae65ed86b9e79aaa74b66441f0811d9cc15Tyler Gunn        if (VDBG) {
2369cf07ae65ed86b9e79aaa74b66441f0811d9cc15Tyler Gunn            Rlog.v(LOG_TAG, "onHangupLocal : " + mCallContext + " state = " + mState);
2379cf07ae65ed86b9e79aaa74b66441f0811d9cc15Tyler Gunn        }
238a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
239a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
240a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /*package*/ ImsPhoneConnection
241a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    getFirstConnection() {
242a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (mConnections.size() == 0) return null;
243a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
244a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return (ImsPhoneConnection) mConnections.get(0);
245a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
246a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
247a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /*package*/ void
248a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    setMute(boolean mute) {
249a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsCall imsCall = getFirstConnection() == null ?
250a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                null : getFirstConnection().getImsCall();
251a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (imsCall != null) {
252a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            try {
253a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                imsCall.setMute(mute);
254a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } catch (ImsException e) {
255a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                Rlog.e(LOG_TAG, "setMute failed : " + e.getMessage());
256a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
257a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
258a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
259a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
260a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /* package */ void
261a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    merge(ImsPhoneCall that, State state) {
26231b502cb274be3c20b993d51192b56f0e7a9ae09Tyler Gunn        // This call is the conference host and the "that" call is the one being merged in.
263fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn        // Set the connect time for the conference; this will have been determined when the
264fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn        // conference was initially created.
265fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn        ImsPhoneConnection imsPhoneConnection = getFirstConnection();
266fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn        if (imsPhoneConnection != null) {
267fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn            long conferenceConnectTime = imsPhoneConnection.getConferenceConnectTime();
268fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn            if (conferenceConnectTime > 0) {
269fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn                imsPhoneConnection.setConnectTime(conferenceConnectTime);
2707ee3f31d9670662a3d4a652860396340b386c29eTyler Gunn            } else {
271707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                if (DBG) {
272707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                    Rlog.d(LOG_TAG, "merge: conference connect time is 0");
273707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                }
274fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn            }
275fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn        }
276707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        if (DBG) {
277707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            Rlog.d(LOG_TAG, "merge(" + mCallContext + "): " + that + "state = "
278707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn                    + state);
279707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        }
280a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
281a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
2820d4f1fe3137cc4a76fc2bb0dac80c68220e53550Tyler Gunn    /**
2830d4f1fe3137cc4a76fc2bb0dac80c68220e53550Tyler Gunn     * Retrieves the {@link ImsCall} for the current {@link ImsPhoneCall}.
2840d4f1fe3137cc4a76fc2bb0dac80c68220e53550Tyler Gunn     * <p>
2850d4f1fe3137cc4a76fc2bb0dac80c68220e53550Tyler Gunn     * Marked as {@code VisibleForTesting} so that the
2860d4f1fe3137cc4a76fc2bb0dac80c68220e53550Tyler Gunn     * {@link com.android.internal.telephony.TelephonyTester} class can inject a test conference
2870d4f1fe3137cc4a76fc2bb0dac80c68220e53550Tyler Gunn     * event package into a regular ongoing IMS call.
2880d4f1fe3137cc4a76fc2bb0dac80c68220e53550Tyler Gunn     *
2890d4f1fe3137cc4a76fc2bb0dac80c68220e53550Tyler Gunn     * @return The {@link ImsCall}.
2900d4f1fe3137cc4a76fc2bb0dac80c68220e53550Tyler Gunn     */
2910d4f1fe3137cc4a76fc2bb0dac80c68220e53550Tyler Gunn    @VisibleForTesting
2920d4f1fe3137cc4a76fc2bb0dac80c68220e53550Tyler Gunn    public ImsCall
293a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    getImsCall() {
294a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return (getFirstConnection() == null) ? null : getFirstConnection().getImsCall();
295a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
296a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
297a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /*package*/ static boolean isLocalTone(ImsCall imsCall) {
298a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if ((imsCall == null) || (imsCall.getCallProfile() == null)
299a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                || (imsCall.getCallProfile().mMediaProfile == null)) {
300a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            return false;
301a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
302a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
303a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        ImsStreamMediaProfile mediaProfile = imsCall.getCallProfile().mMediaProfile;
304a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
305a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return (mediaProfile.mAudioDirection == ImsStreamMediaProfile.DIRECTION_INACTIVE)
306a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                ? true : false;
307a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
308a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
309f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxu    public boolean update (ImsPhoneConnection conn, ImsCall imsCall, State state) {
310a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        boolean changed = false;
3119cf07ae65ed86b9e79aaa74b66441f0811d9cc15Tyler Gunn        State oldState = mState;
312a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
313a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        //ImsCall.Listener.onCallProgressing can be invoked several times
314a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        //and ringback tone mode can be changed during the call setup procedure
315a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        if (state == State.ALERTING) {
316a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (mRingbackTonePlayed && !isLocalTone(imsCall)) {
317a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mOwner.mPhone.stopRingbackTone();
318a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mRingbackTonePlayed = false;
319a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            } else if (!mRingbackTonePlayed && isLocalTone(imsCall)) {
320a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mOwner.mPhone.startRingbackTone();
321a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mRingbackTonePlayed = true;
322a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
323a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else {
324a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            if (mRingbackTonePlayed) {
325a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mOwner.mPhone.stopRingbackTone();
326a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville                mRingbackTonePlayed = false;
327a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            }
328a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
329a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3309cf07ae65ed86b9e79aaa74b66441f0811d9cc15Tyler Gunn        if ((state != mState) && (state != State.DISCONNECTED)) {
3319cf07ae65ed86b9e79aaa74b66441f0811d9cc15Tyler Gunn            mState = state;
332a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            changed = true;
333a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        } else if (state == State.DISCONNECTED) {
334a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            changed = true;
335a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
336a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
3379cf07ae65ed86b9e79aaa74b66441f0811d9cc15Tyler Gunn        if (VDBG) {
3389cf07ae65ed86b9e79aaa74b66441f0811d9cc15Tyler Gunn            Rlog.v(LOG_TAG, "update : " + mCallContext + " state: " + oldState + " --> " + mState);
3399cf07ae65ed86b9e79aaa74b66441f0811d9cc15Tyler Gunn        }
3409cf07ae65ed86b9e79aaa74b66441f0811d9cc15Tyler Gunn
341a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        return changed;
342a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
343a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
344a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    /* package */ ImsPhoneConnection
345a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    getHandoverConnection() {
3462c38178d30afd3f168c6506f0942f93c785d3d7eTyler Gunn        return (ImsPhoneConnection) getEarliestConnection();
347a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
348a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
349f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxu    public void switchWith(ImsPhoneCall that) {
350707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        if (VDBG) {
351707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn            Rlog.v(LOG_TAG, "switchWith : switchCall = " + this + " withCall = " + that);
352707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        }
353a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        synchronized (ImsPhoneCall.class) {
354a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ImsPhoneCall tmp = new ImsPhoneCall();
355a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            tmp.takeOver(this);
356a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            this.takeOver(that);
357a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            that.takeOver(tmp);
358a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
359707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn        mOwner.logState();
360a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
361a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville
362a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    private void takeOver(ImsPhoneCall that) {
363a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mConnections = that.mConnections;
364a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        mState = that.mState;
365a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        for (Connection c : mConnections) {
366a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville            ((ImsPhoneConnection) c).changeParent(this);
367a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville        }
368a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville    }
369a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville}
370