ImsCall.java revision d1edfd8cf9ffeb191a84e08522bb570cd8cd4381
1ef36ef67e009449300b0150c60c9f637e205d79eWink Saville/*
2ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Copyright (c) 2013 The Android Open Source Project
3ef36ef67e009449300b0150c60c9f637e205d79eWink Saville *
4ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Licensed under the Apache License, Version 2.0 (the "License");
5ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * you may not use this file except in compliance with the License.
6ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * You may obtain a copy of the License at
7ef36ef67e009449300b0150c60c9f637e205d79eWink Saville *
8ef36ef67e009449300b0150c60c9f637e205d79eWink Saville *      http://www.apache.org/licenses/LICENSE-2.0
9ef36ef67e009449300b0150c60c9f637e205d79eWink Saville *
10ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Unless required by applicable law or agreed to in writing, software
11ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * distributed under the License is distributed on an "AS IS" BASIS,
12ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * See the License for the specific language governing permissions and
14ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * limitations under the License.
15ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */
16ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
17ef36ef67e009449300b0150c60c9f637e205d79eWink Savillepackage com.android.ims;
18ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
19ca45f58a57eb782153c034ae067f59c0018799caUma Maheswari Ramalingamimport com.android.internal.R;
20ca45f58a57eb782153c034ae067f59c0018799caUma Maheswari Ramalingam
21ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport java.util.ArrayList;
22ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport java.util.HashMap;
23ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport java.util.Iterator;
24ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport java.util.Map.Entry;
25ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport java.util.Set;
26ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
27ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport android.content.Context;
28ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport android.os.Bundle;
29ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport android.os.Message;
30ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport android.telephony.Rlog;
31ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
32ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport com.android.ims.internal.CallGroup;
33ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport com.android.ims.internal.CallGroupManager;
34ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport com.android.ims.internal.ICall;
35ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport com.android.ims.internal.ImsCallSession;
36ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport com.android.ims.internal.ImsStreamMediaSession;
37ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
38ef36ef67e009449300b0150c60c9f637e205d79eWink Saville/**
39ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Handles an IMS voice / video call over LTE. You can instantiate this class with
40ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * {@link ImsManager}.
41ef36ef67e009449300b0150c60c9f637e205d79eWink Saville *
42ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @hide
43ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */
44ef36ef67e009449300b0150c60c9f637e205d79eWink Savillepublic class ImsCall implements ICall {
45ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public static final int CALL_STATE_ACTIVE_TO_HOLD = 1;
46ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public static final int CALL_STATE_HOLD_TO_ACTIVE = 2;
47ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
48ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    // Mode of USSD message
49ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public static final int USSD_MODE_NOTIFY = 0;
50ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public static final int USSD_MODE_REQUEST = 1;
51ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
52ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private static final String TAG = "ImsCall";
53ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private static final boolean DBG = true;
54ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
55ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
56ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Listener for events relating to an IMS call, such as when a call is being
57ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * recieved ("on ringing") or a call is outgoing ("on calling").
58ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * <p>Many of these events are also received by {@link ImsCallSession.Listener}.</p>
59ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
60ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public static class Listener {
61ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
62ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when a request is sent out to initiate a new call
63ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * and 1xx response is received from the network.
64ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * The default implementation calls {@link #onCallStateChanged}.
65ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
66ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
67ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
68ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallProgressing(ImsCall call) {
69ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            onCallStateChanged(call);
70ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
71ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
72ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
73ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the call is established.
74ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * The default implementation calls {@link #onCallStateChanged}.
75ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
76ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
77ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
78ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallStarted(ImsCall call) {
79ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            onCallStateChanged(call);
80ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
81ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
82ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
83ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the call setup is failed.
84ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * The default implementation calls {@link #onCallError}.
85ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
86ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
87ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param reasonInfo detailed reason of the call setup failure
88ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
89ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallStartFailed(ImsCall call, ImsReasonInfo reasonInfo) {
90ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            onCallError(call, reasonInfo);
91ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
92ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
93ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
94ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the call is terminated.
95ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * The default implementation calls {@link #onCallStateChanged}.
96ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
97ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
98ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param reasonInfo detailed reason of the call termination
99ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
100ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallTerminated(ImsCall call, ImsReasonInfo reasonInfo) {
101ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            // Store the call termination reason
102ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
103ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            onCallStateChanged(call);
104ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
105ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
106ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
107ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the call is in hold.
108ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * The default implementation calls {@link #onCallStateChanged}.
109ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
110ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
111ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
112ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallHeld(ImsCall call) {
113ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            onCallStateChanged(call);
114ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
115ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
116ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
117ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the call hold is failed.
118ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * The default implementation calls {@link #onCallError}.
119ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
120ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
121ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param reasonInfo detailed reason of the call hold failure
122ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
123ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallHoldFailed(ImsCall call, ImsReasonInfo reasonInfo) {
124ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            onCallError(call, reasonInfo);
125ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
126ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
127ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
128ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the call hold is received from the remote user.
129ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * The default implementation calls {@link #onCallStateChanged}.
130ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
131ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
132ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
133ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallHoldReceived(ImsCall call) {
134ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            onCallStateChanged(call);
135ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
136ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
137ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
138ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the call is in call.
139ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * The default implementation calls {@link #onCallStateChanged}.
140ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
141ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
142ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
143ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallResumed(ImsCall call) {
144ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            onCallStateChanged(call);
145ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
146ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
147ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
148ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the call resume is failed.
149ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * The default implementation calls {@link #onCallError}.
150ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
151ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
152ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param reasonInfo detailed reason of the call resume failure
153ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
154ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallResumeFailed(ImsCall call, ImsReasonInfo reasonInfo) {
155ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            onCallError(call, reasonInfo);
156ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
157ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
158ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
159ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the call resume is received from the remote user.
160ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * The default implementation calls {@link #onCallStateChanged}.
161ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
162ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
163ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
164ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallResumeReceived(ImsCall call) {
165ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            onCallStateChanged(call);
166ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
167ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
168ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
169ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the call is in call.
170ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * The default implementation calls {@link #onCallStateChanged}.
171ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
172ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
173ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param newCall the call object that is merged with an active & hold call
174ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
175ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallMerged(ImsCall call, ImsCall newCall) {
176ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            onCallStateChanged(call, newCall);
177ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
178ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
179ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
180ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the call merge is failed.
181ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * The default implementation calls {@link #onCallError}.
182ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
183ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
184ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param reasonInfo detailed reason of the call merge failure
185ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
186ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallMergeFailed(ImsCall call, ImsReasonInfo reasonInfo) {
187ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            onCallError(call, reasonInfo);
188ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
189ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
190ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
191ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the call is updated (except for hold/unhold).
192ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * The default implementation calls {@link #onCallStateChanged}.
193ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
194ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
195ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
196ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallUpdated(ImsCall call) {
197ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            onCallStateChanged(call);
198ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
199ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
200ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
201ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the call update is failed.
202ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * The default implementation calls {@link #onCallError}.
203ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
204ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
205ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param reasonInfo detailed reason of the call update failure
206ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
207ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallUpdateFailed(ImsCall call, ImsReasonInfo reasonInfo) {
208ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            onCallError(call, reasonInfo);
209ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
210ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
211ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
212ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the call update is received from the remote user.
213ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
214ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
215ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
216ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallUpdateReceived(ImsCall call) {
217ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            // no-op
218ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
219ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
220ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
221ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the call is extended to the conference call.
222ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * The default implementation calls {@link #onCallStateChanged}.
223ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
224ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
225ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param newCall the call object that is extended to the conference from the active call
226ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
227ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallConferenceExtended(ImsCall call, ImsCall newCall) {
228ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            onCallStateChanged(call, newCall);
229ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
230ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
231ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
232ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the conference extension is failed.
233ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * The default implementation calls {@link #onCallError}.
234ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
235ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
236ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param reasonInfo detailed reason of the conference extension failure
237ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
238ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallConferenceExtendFailed(ImsCall call,
239ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsReasonInfo reasonInfo) {
240ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            onCallError(call, reasonInfo);
241ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
242ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
243ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
244ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the conference extension is received from the remote user.
245ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
246ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
247ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param newCall the call object that is extended to the conference from the active call
248ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
249ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallConferenceExtendReceived(ImsCall call, ImsCall newCall) {
250ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            onCallStateChanged(call, newCall);
251ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
252ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
253ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
254ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the invitation request of the participants is delivered to
255ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * the conference server.
256ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
257ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
258ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
259ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallInviteParticipantsRequestDelivered(ImsCall call) {
260ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            // no-op
261ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
262ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
263ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
264ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the invitation request of the participants is failed.
265ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
266ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
267ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param reasonInfo detailed reason of the conference invitation failure
268ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
269ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallInviteParticipantsRequestFailed(ImsCall call,
270ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsReasonInfo reasonInfo) {
271ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            // no-op
272ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
273ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
274ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
275ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the removal request of the participants is delivered to
276ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * the conference server.
277ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
278ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
279ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
280ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallRemoveParticipantsRequestDelivered(ImsCall call) {
281ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            // no-op
282ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
283ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
284ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
285ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the removal request of the participants is failed.
286ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
287ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
288ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param reasonInfo detailed reason of the conference removal failure
289ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
290ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallRemoveParticipantsRequestFailed(ImsCall call,
291ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsReasonInfo reasonInfo) {
292ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            // no-op
293ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
294ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
295ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
296ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the conference state is updated.
297ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
298ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
299ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param state state of the participant who is participated in the conference call
300ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
301ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallConferenceStateUpdated(ImsCall call, ImsConferenceState state) {
302ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            // no-op
303ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
304ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
305ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
306ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the USSD message is received from the network.
307ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
308ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param mode mode of the USSD message (REQUEST / NOTIFY)
309ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param ussdMessage USSD message
310ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
311ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallUssdMessageReceived(ImsCall call,
312ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                int mode, String ussdMessage) {
313ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            // no-op
314ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
315ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
316ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
317ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when an error occurs. The default implementation is no op.
318ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * overridden. The default implementation is no op. Error events are
319ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * not re-directed to this callback and are handled in {@link #onCallError}.
320ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
321ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
322ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param reasonInfo detailed reason of this error
323ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @see ImsReasonInfo
324ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
325ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallError(ImsCall call, ImsReasonInfo reasonInfo) {
326ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            // no-op
327ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
328ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
329ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
330ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when an event occurs and the corresponding callback is not
331ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * overridden. The default implementation is no op. Error events are
332ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * not re-directed to this callback and are handled in {@link #onCallError}.
333ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
334ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
335ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
336ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallStateChanged(ImsCall call) {
337ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            // no-op
338ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
339ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
340ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
341ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when an event occurs and the corresponding callback is not
342ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * overridden. The default implementation is no op. Error events are
343ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * not re-directed to this callback and are handled in {@link #onCallError}.
344ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
345ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
346ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param newCall the call object that will be replaced by the previous call
347ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
348ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallStateChanged(ImsCall call, ImsCall newCall) {
349ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            // no-op
350ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
351ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
352ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        /**
353ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * Called when the call moves the hold state to the conversation state.
354ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * For example, when merging the active & hold call, the state of all the hold call
355ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * will be changed from hold state to conversation state.
356ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * This callback method can be invoked even though the application does not trigger
357ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * any operations.
358ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *
359ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param call the call object that carries out the IMS call
360ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         * @param state the detailed state of call state changes;
361ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         *      Refer to CALL_STATE_* in {@link ImsCall}
362ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         */
363ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void onCallStateChanged(ImsCall call, int state) {
364ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            // no-op
365ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
366ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
367ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
368ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
369ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
370ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    // List of update operation for IMS call control
371ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private static final int UPDATE_NONE = 0;
372ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private static final int UPDATE_HOLD = 1;
373ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private static final int UPDATE_HOLD_MERGE = 2;
374ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private static final int UPDATE_RESUME = 3;
375ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private static final int UPDATE_MERGE = 4;
376ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private static final int UPDATE_EXTEND_TO_CONFERENCE = 5;
377ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private static final int UPDATE_UNSPECIFIED = 6;
378ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
379ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    // For synchronization of private variables
380ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private Object mLockObj = new Object();
381ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private Context mContext;
382ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
383ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    // true if the call is established & in the conversation state
384ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private boolean mInCall = false;
385ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    // true if the call is on hold
386ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    // If it is triggered by the local, mute the call. Otherwise, play local hold tone
387ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    // or network generated media.
388ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private boolean mHold = false;
389ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    // true if the call is on mute
390ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private boolean mMute = false;
391ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    // It contains the exclusive call update request. Refer to UPDATE_*.
392ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private int mUpdateRequest = UPDATE_NONE;
393ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
394ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private ImsCall.Listener mListener = null;
395ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    // It is for managing the multiple calls
396ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    // when the multiparty call is extended to the conference.
397ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private CallGroup mCallGroup = null;
398ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
399ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    // Wrapper call session to interworking the IMS service (server).
400ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private ImsCallSession mSession = null;
401ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    // Call profile of the current session.
402ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    // It can be changed at anytime when the call is updated.
403ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private ImsCallProfile mCallProfile = null;
404ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    // Call profile to be updated after the application's action (accept/reject)
405ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    // to the call update. After the application's action (accept/reject) is done,
406ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    // it will be set to null.
407ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private ImsCallProfile mProposedCallProfile = null;
408ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private ImsReasonInfo mLastReasonInfo = null;
409ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
410ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    // Media session to control media (audio/video) operations for an IMS call
411ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private ImsStreamMediaSession mMediaSession = null;
412ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
413ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
414ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Create an IMS call object.
415ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
416ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param context the context for accessing system services
417ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param profile the call profile to make/take a call
418ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
419ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public ImsCall(Context context, ImsCallProfile profile) {
420ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        mContext = context;
421ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        mCallProfile = profile;
422ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
423ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
424ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
425ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Closes this object. This object is not usable after being closed.
426ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
427ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    @Override
428ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public void close() {
429ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
430ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            destroyCallGroup();
431ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
432ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mSession != null) {
433ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mSession.close();
434ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mSession = null;
435ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
436ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
437ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mCallProfile = null;
438ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mProposedCallProfile = null;
439ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mLastReasonInfo = null;
440ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mMediaSession = null;
441ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
442ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
443ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
444ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
445ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Checks if the call has a same remote user identity or not.
446ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
447ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param userId the remote user identity
448ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @return true if the remote user identity is equal; otherwise, false
449ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
450ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    @Override
451ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public boolean checkIfRemoteUserIsSame(String userId) {
452ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (userId == null) {
453ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return false;
454ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
455ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
456ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        return userId.equals(mCallProfile.getCallExtra(ImsCallProfile.EXTRA_REMOTE_URI, ""));
457ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
458ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
459ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
460ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Checks if the call is equal or not.
461ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
462ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param call the call to be compared
463ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @return true if the call is equal; otherwise, false
464ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
465ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    @Override
466ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public boolean equalsTo(ICall call) {
467ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (call == null) {
468ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return false;
469ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
470ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
471ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (call instanceof ImsCall) {
472ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return this.equals((ImsCall)call);
473ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
474ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
475ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        return false;
476ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
477ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
478ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
479ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Gets the negotiated (local & remote) call profile.
480ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
481ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @return a {@link ImsCallProfile} object that has the negotiated call profile
482ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
483ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public ImsCallProfile getCallProfile() {
484ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
485ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return mCallProfile;
486ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
487ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
488ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
489ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
490ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Gets the local call profile (local capabilities).
491ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
492ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @return a {@link ImsCallProfile} object that has the local call profile
493ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
494ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public ImsCallProfile getLocalCallProfile() throws ImsException {
495ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
496ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mSession == null) {
497ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                throw new ImsException("No call session",
498ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED);
499ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
500ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
501ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            try {
502ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                return mSession.getLocalCallProfile();
503ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            } catch (Throwable t) {
504ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                loge("getLocalCallProfile :: ", t);
505ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                throw new ImsException("getLocalCallProfile()", t, 0);
506ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
507ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
508ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
509ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
510ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
511ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Gets the call profile proposed by the local/remote user.
512ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
513ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @return a {@link ImsCallProfile} object that has the proposed call profile
514ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
515ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public ImsCallProfile getProposedCallProfile() {
516ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
517ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (!isInCall()) {
518ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                return null;
519ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
520ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
521ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return mProposedCallProfile;
522ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
523ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
524ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
525ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
526ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Gets the state of the {@link ImsCallSession} that carries this call.
527ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * The value returned must be one of the states in {@link ImsCallSession#State}.
528ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
529ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @return the session state
530ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
531ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public int getState() {
532ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
533ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mSession == null) {
534ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                return ImsCallSession.State.IDLE;
535ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
536ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
537ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return mSession.getState();
538ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
539ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
540ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
541ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
542ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Gets the {@link ImsCallSession} that carries this call.
543ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
544ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @return the session object that carries this call
545ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @hide
546ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
547ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public ImsCallSession getCallSession() {
548ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
549ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return mSession;
550ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
551ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
552ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
553ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
554ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Gets the {@link ImsStreamMediaSession} that handles the media operation of this call.
555ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Almost interface APIs are for the VT (Video Telephony).
556ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
557ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @return the media session object that handles the media operation of this call
558ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @hide
559ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
560ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public ImsStreamMediaSession getMediaSession() {
561ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
562ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return mMediaSession;
563ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
564ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
565ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
566ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
567ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Gets the specified property of this call.
568ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
569ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param name key to get the extra call information defined in {@link ImsCallProfile}
570ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @return the extra call information as string
571ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
572ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public String getCallExtra(String name) throws ImsException {
573ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        // Lookup the cache
574ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
575ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
576ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            // If not found, try to get the property from the remote
577ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mSession == null) {
578ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                throw new ImsException("No call session",
579ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED);
580ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
581ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
582ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            try {
583ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                return mSession.getProperty(name);
584ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            } catch (Throwable t) {
585ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                loge("getCallExtra :: ", t);
586ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                throw new ImsException("getCallExtra()", t, 0);
587ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
588ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
589ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
590ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
591ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
592ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Gets the last reason information when the call is not established, cancelled or terminated.
593ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
594ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @return the last reason information
595ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
596ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public ImsReasonInfo getLastReasonInfo() {
597ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
598ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return mLastReasonInfo;
599ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
600ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
601ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
602ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
603ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Checks if the call has a pending update operation.
604ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
605ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @return true if the call has a pending update operation
606ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
607ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public boolean hasPendingUpdate() {
608ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
609ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return (mUpdateRequest != UPDATE_NONE);
610ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
611ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
612ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
613ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
614ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Checks if the call is established.
615ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
616ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @return true if the call is established
617ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
618ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public boolean isInCall() {
619ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
620ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return mInCall;
621ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
622ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
623ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
624ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
625ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Checks if the call is muted.
626ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
627ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @return true if the call is muted
628ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
629ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public boolean isMuted() {
630ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
631ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return mMute;
632ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
633ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
634ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
635ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
636ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Checks if the call is on hold.
637ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
638ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @return true if the call is on hold
639ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
640ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public boolean isOnHold() {
641ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
642ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return mHold;
643ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
644ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
645ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
646ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
647ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Sets the listener to listen to the IMS call events.
648ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * The method calls {@link #setListener setListener(listener, false)}.
649ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
650ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param listener to listen to the IMS call events of this object; null to remove listener
651ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @see #setListener(Listener, boolean)
652ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
653ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public void setListener(ImsCall.Listener listener) {
654ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        setListener(listener, false);
655ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
656ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
657ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
658ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Sets the listener to listen to the IMS call events.
659ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * A {@link ImsCall} can only hold one listener at a time. Subsequent calls
660ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * to this method override the previous listener.
661ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
662ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param listener to listen to the IMS call events of this object; null to remove listener
663ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param callbackImmediately set to true if the caller wants to be called
664ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *        back immediately on the current state
665ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
666ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public void setListener(ImsCall.Listener listener, boolean callbackImmediately) {
667ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        boolean inCall;
668ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        boolean onHold;
669ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        int state;
670ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        ImsReasonInfo lastReasonInfo;
671ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
672ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
673ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mListener = listener;
674ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
675ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if ((listener == null) || !callbackImmediately) {
676ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                return;
677ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
678ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
679ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            inCall = mInCall;
680ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            onHold = mHold;
681ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            state = getState();
682ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            lastReasonInfo = mLastReasonInfo;
683ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
684ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
685ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        try {
686ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (lastReasonInfo != null) {
687ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener.onCallError(this, lastReasonInfo);
688ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            } else if (inCall) {
689ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                if (onHold) {
690ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallHeld(this);
691ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } else {
692ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallStarted(this);
693ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
694ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            } else {
695ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                switch (state) {
696ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    case ImsCallSession.State.ESTABLISHING:
697ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        listener.onCallProgressing(this);
698ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        break;
699ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    case ImsCallSession.State.TERMINATED:
700ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        listener.onCallTerminated(this, lastReasonInfo);
701ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        break;
702ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    default:
703ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        // Ignore it. There is no action in the other state.
704ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        break;
705ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
706ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
707ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        } catch (Throwable t) {
708ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            loge("setListener()", t);
709ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
710ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
711ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
712ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
713ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Mutes or unmutes the mic for the active call.
714ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
715ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param muted true if the call is muted, false otherwise
716ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
717ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public void setMute(boolean muted) throws ImsException {
718ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
719ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mMute != muted) {
720ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mMute = muted;
721ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
722ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
723ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    mSession.setMute(muted);
724ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
725ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("setMute :: ", t);
726ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    throwImsException(t, 0);
727ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
728ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
729ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
730ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
731ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
732ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     /**
733ef36ef67e009449300b0150c60c9f637e205d79eWink Saville      * Attaches an incoming call to this call object.
734ef36ef67e009449300b0150c60c9f637e205d79eWink Saville      *
735ef36ef67e009449300b0150c60c9f637e205d79eWink Saville      * @param session the session that receives the incoming call
736ef36ef67e009449300b0150c60c9f637e205d79eWink Saville      * @throws ImsException if the IMS service fails to attach this object to the session
737ef36ef67e009449300b0150c60c9f637e205d79eWink Saville      */
738ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     public void attachSession(ImsCallSession session) throws ImsException {
739ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         if (DBG) {
740ef36ef67e009449300b0150c60c9f637e205d79eWink Saville             log("attachSession :: session=" + session);
741ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         }
742ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
743ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         synchronized(mLockObj) {
744ef36ef67e009449300b0150c60c9f637e205d79eWink Saville             mSession = session;
745ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
746ef36ef67e009449300b0150c60c9f637e205d79eWink Saville             try {
747ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                 mSession.setListener(createCallSessionListener());
748ef36ef67e009449300b0150c60c9f637e205d79eWink Saville             } catch (Throwable t) {
749ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                 loge("attachSession :: ", t);
750ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                 throwImsException(t, 0);
751ef36ef67e009449300b0150c60c9f637e205d79eWink Saville             }
752ef36ef67e009449300b0150c60c9f637e205d79eWink Saville         }
753ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     }
754ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
755ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
756ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Initiates an IMS call with the call profile which is provided
757ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * when creating a {@link ImsCall}.
758ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
759ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param session the {@link ImsCallSession} for carrying out the call
760ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param callee callee information to initiate an IMS call
761ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @throws ImsException if the IMS service fails to initiate the call
762ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
763ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public void start(ImsCallSession session, String callee)
764ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            throws ImsException {
765ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (DBG) {
766ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            log("start(1) :: session=" + session + ", callee=" + callee);
767ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
768ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
769ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
770ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mSession = session;
771ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
772ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            try {
773ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                session.setListener(createCallSessionListener());
774ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                session.start(callee, mCallProfile);
775ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            } catch (Throwable t) {
776ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                loge("start(1) :: ", t);
777ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                throw new ImsException("start(1)", t, 0);
778ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
779ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
780ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
781ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
782ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
783ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Initiates an IMS conferenca call with the call profile which is provided
784ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * when creating a {@link ImsCall}.
785ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
786ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param session the {@link ImsCallSession} for carrying out the call
787ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param participants participant list to initiate an IMS conference call
788ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @throws ImsException if the IMS service fails to initiate the call
789ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
790ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public void start(ImsCallSession session, String[] participants)
791ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            throws ImsException {
792ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (DBG) {
793ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            log("start(n) :: session=" + session + ", callee=" + participants);
794ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
795ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
796ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
797ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mSession = session;
798ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
799ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            try {
800ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                session.setListener(createCallSessionListener());
801ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                session.start(participants, mCallProfile);
802ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            } catch (Throwable t) {
803ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                loge("start(n) :: ", t);
804ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                throw new ImsException("start(n)", t, 0);
805ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
806ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
807ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
808ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
809ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
810ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Accepts a call.
811ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
812ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @see Listener#onCallStarted
813d1edfd8cf9ffeb191a84e08522bb570cd8cd4381Tyler Gunn     *
814d1edfd8cf9ffeb191a84e08522bb570cd8cd4381Tyler Gunn     * @param callType The call type the user agreed to for accepting the call.
815ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @throws ImsException if the IMS service fails to accept the call
816ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
817d1edfd8cf9ffeb191a84e08522bb570cd8cd4381Tyler Gunn    public void accept(int callType) throws ImsException {
818ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (DBG) {
819ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            log("accept :: session=" + mSession);
820ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
821ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
822d1edfd8cf9ffeb191a84e08522bb570cd8cd4381Tyler Gunn        accept(callType, new ImsStreamMediaProfile());
823ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
824ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
825ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
826ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Accepts a call.
827ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
828ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param callType call type to be answered in {@link ImsCallProfile}
829ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param profile a media profile to be answered (audio/audio & video, direction, ...)
830ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @see Listener#onCallStarted
831ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @throws ImsException if the IMS service fails to accept the call
832ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
833ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public void accept(int callType, ImsStreamMediaProfile profile) throws ImsException {
834ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (DBG) {
835ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            log("accept :: session=" + mSession
836ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    + ", callType=" + callType + ", profile=" + profile);
837ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
838ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
839ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
840ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mSession == null) {
841ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                throw new ImsException("No call to answer",
842ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED);
843ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
844ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
845ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            try {
846ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mSession.accept(callType, profile);
847ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            } catch (Throwable t) {
848ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                loge("accept :: ", t);
849ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                throw new ImsException("accept()", t, 0);
850ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
851ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
852ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mInCall && (mProposedCallProfile != null)) {
853ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                if (DBG) {
854ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    log("accept :: call profile will be updated");
855ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
856ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
857ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mCallProfile = mProposedCallProfile;
858ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mProposedCallProfile = null;
859ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
860ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
861ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            // Other call update received
862ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mInCall && (mUpdateRequest == UPDATE_UNSPECIFIED)) {
863ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mUpdateRequest = UPDATE_NONE;
864ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
865ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
866ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
867ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
868ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
869ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Rejects a call.
870ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
871ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param reason reason code to reject an incoming call
872ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @see Listener#onCallStartFailed
873ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @throws ImsException if the IMS service fails to accept the call
874ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
875ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public void reject(int reason) throws ImsException {
876ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (DBG) {
877ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            log("reject :: session=" + mSession + ", reason=" + reason);
878ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
879ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
880ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
881ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mSession != null) {
882ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mSession.reject(reason);
883ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
884ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
885ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mInCall && (mProposedCallProfile != null)) {
886ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                if (DBG) {
887ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    log("reject :: call profile is not updated; destroy it...");
888ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
889ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
890ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mProposedCallProfile = null;
891ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
892ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
893ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            // Other call update received
894ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mInCall && (mUpdateRequest == UPDATE_UNSPECIFIED)) {
895ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mUpdateRequest = UPDATE_NONE;
896ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
897ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
898ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
899ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
900ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
901ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Terminates an IMS call.
902ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
903ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param reason reason code to terminate a call
904ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @throws ImsException if the IMS service fails to terminate the call
905ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
906ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public void terminate(int reason) throws ImsException {
907ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (DBG) {
908ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            log("terminate :: session=" + mSession + ", reason=" + reason);
909ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
910ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
911ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
912ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mHold = false;
913ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mInCall = false;
914ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
915ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mSession != null) {
916ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mSession.terminate(reason);
917ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
918ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
919ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
920ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
921ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
922ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Puts a call on hold. When succeeds, {@link Listener#onCallHeld} is called.
923ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
924ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @see Listener#onCallHeld, Listener#onCallHoldFailed
925ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @throws ImsException if the IMS service fails to hold the call
926ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
927ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public void hold() throws ImsException {
928ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (DBG) {
929ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            log("hold :: session=" + mSession);
930ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
931ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
932ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (isOnHold()) {
933ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
934ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("hold :: call is already on hold");
935ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
936ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return;
937ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
938ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
939ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
940ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mUpdateRequest != UPDATE_NONE) {
941ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                loge("hold :: update is in progress; request=" + mUpdateRequest);
942ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                throw new ImsException("Call update is in progress",
943ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ImsReasonInfo.CODE_LOCAL_ILLEGAL_STATE);
944ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
945ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
946ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mSession == null) {
947ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                loge("hold :: ");
948ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                throw new ImsException("No call session",
949ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED);
950ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
951ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
952ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mSession.hold(createHoldMediaProfile());
953ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            // FIXME: update the state on the callback?
954ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mHold = true;
955ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mUpdateRequest = UPDATE_HOLD;
956ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
957ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
958ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
959ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
960ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Continues a call that's on hold. When succeeds, {@link Listener#onCallResumed} is called.
961ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
962ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @see Listener#onCallResumed, Listener#onCallResumeFailed
963ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @throws ImsException if the IMS service fails to resume the call
964ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
965ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public void resume() throws ImsException {
966ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (DBG) {
967ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            log("resume :: session=" + mSession);
968ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
969ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
970ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (!isOnHold()) {
971ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
972ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("resume :: call is in conversation");
973ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
974ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return;
975ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
976ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
977ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
978ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mUpdateRequest != UPDATE_NONE) {
979ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                loge("resume :: update is in progress; request=" + mUpdateRequest);
980ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                throw new ImsException("Call update is in progress",
981ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ImsReasonInfo.CODE_LOCAL_ILLEGAL_STATE);
982ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
983ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
984ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mSession == null) {
985ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                loge("resume :: ");
986ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                throw new ImsException("No call session",
987ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED);
988ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
989ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
990ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mSession.resume(createResumeMediaProfile());
991ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            // FIXME: update the state on the callback?
992ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mHold = false;
993ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mUpdateRequest = UPDATE_RESUME;
994ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
995ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
996ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
997ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
998ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Merges the active & hold call.
999ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
1000ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @see Listener#onCallMerged, Listener#onCallMergeFailed
1001ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @throws ImsException if the IMS service fails to merge the call
1002ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
1003ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public void merge() throws ImsException {
1004ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (DBG) {
1005ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            log("merge :: session=" + mSession);
1006ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1007ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1008ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
1009ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mUpdateRequest != UPDATE_NONE) {
1010ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                loge("merge :: update is in progress; request=" + mUpdateRequest);
1011ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                throw new ImsException("Call update is in progress",
1012ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ImsReasonInfo.CODE_LOCAL_ILLEGAL_STATE);
1013ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1014ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1015ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mSession == null) {
1016ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                loge("merge :: ");
1017ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                throw new ImsException("No call session",
1018ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED);
1019ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1020ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1021ca45f58a57eb782153c034ae067f59c0018799caUma Maheswari Ramalingam            // if skipHoldBeforeMerge = true, IMS service implementation will
1022ca45f58a57eb782153c034ae067f59c0018799caUma Maheswari Ramalingam            // merge without explicitly holding the call.
1023ca45f58a57eb782153c034ae067f59c0018799caUma Maheswari Ramalingam            if (mHold || (mContext.getResources().getBoolean(
1024ca45f58a57eb782153c034ae067f59c0018799caUma Maheswari Ramalingam                    com.android.internal.R.bool.skipHoldBeforeMerge))) {
1025ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mSession.merge();
1026ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mUpdateRequest = UPDATE_MERGE;
1027ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            } else {
1028ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mSession.hold(createHoldMediaProfile());
1029ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                // FIXME: ?
1030ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mHold = true;
1031ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mUpdateRequest = UPDATE_HOLD_MERGE;
1032ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1033ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1034ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1035ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1036ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
1037ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Merges the active & hold call.
1038ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
1039ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param bgCall the background (holding) call
1040ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @see Listener#onCallMerged, Listener#onCallMergeFailed
1041ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @throws ImsException if the IMS service fails to merge the call
1042ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
1043ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public void merge(ImsCall bgCall) throws ImsException {
1044ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (DBG) {
1045ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            log("merge(1) :: session=" + mSession);
1046ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1047ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1048ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (bgCall == null) {
1049ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            throw new ImsException("No background call",
1050ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
1051ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1052ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1053ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
1054ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            createCallGroup(bgCall);
1055ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1056ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1057ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        merge();
1058ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1059ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1060ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
1061ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Updates the current call's properties (ex. call mode change: video upgrade / downgrade).
1062ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
1063ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public void update(int callType, ImsStreamMediaProfile mediaProfile) throws ImsException {
1064ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (DBG) {
1065ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            log("update :: session=" + mSession);
1066ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1067ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1068ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (isOnHold()) {
1069ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
1070ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("update :: call is on hold");
1071ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1072ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            throw new ImsException("Not in a call to update call",
1073ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    ImsReasonInfo.CODE_LOCAL_ILLEGAL_STATE);
1074ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1075ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1076ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
1077ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mUpdateRequest != UPDATE_NONE) {
1078ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                if (DBG) {
1079ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    log("update :: update is in progress; request=" + mUpdateRequest);
1080ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1081ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                throw new ImsException("Call update is in progress",
1082ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ImsReasonInfo.CODE_LOCAL_ILLEGAL_STATE);
1083ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1084ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1085ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mSession == null) {
1086ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                loge("update :: ");
1087ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                throw new ImsException("No call session",
1088ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED);
1089ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1090ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1091ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mSession.update(callType, mediaProfile);
1092ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mUpdateRequest = UPDATE_UNSPECIFIED;
1093ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1094ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1095ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1096ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
1097ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Extends this call (1-to-1 call) to the conference call
1098ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * inviting the specified participants to.
1099ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
1100ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
1101ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public void extendToConference(String[] participants) throws ImsException {
1102ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (DBG) {
1103ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            log("extendToConference :: session=" + mSession);
1104ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1105ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1106ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (isOnHold()) {
1107ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
1108ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("extendToConference :: call is on hold");
1109ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1110ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            throw new ImsException("Not in a call to extend a call to conference",
1111ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    ImsReasonInfo.CODE_LOCAL_ILLEGAL_STATE);
1112ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1113ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1114ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
1115ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mUpdateRequest != UPDATE_NONE) {
1116ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                if (DBG) {
1117ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    log("extendToConference :: update is in progress; request=" + mUpdateRequest);
1118ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1119ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                throw new ImsException("Call update is in progress",
1120ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ImsReasonInfo.CODE_LOCAL_ILLEGAL_STATE);
1121ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1122ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1123ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mSession == null) {
1124ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                loge("extendToConference :: ");
1125ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                throw new ImsException("No call session",
1126ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED);
1127ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1128ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1129ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mSession.extendToConference(participants);
1130ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mUpdateRequest = UPDATE_EXTEND_TO_CONFERENCE;
1131ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1132ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1133ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1134ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
1135ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Requests the conference server to invite an additional participants to the conference.
1136ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
1137ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
1138ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public void inviteParticipants(String[] participants) throws ImsException {
1139ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (DBG) {
1140ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            log("inviteParticipants :: session=" + mSession);
1141ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1142ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1143ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
1144ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mSession == null) {
1145ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                loge("inviteParticipants :: ");
1146ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                throw new ImsException("No call session",
1147ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED);
1148ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1149ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1150ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mSession.inviteParticipants(participants);
1151ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1152ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1153ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1154ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
1155ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Requests the conference server to remove the specified participants from the conference.
1156ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
1157ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
1158ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public void removeParticipants(String[] participants) throws ImsException {
1159ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (DBG) {
1160ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            log("removeParticipants :: session=" + mSession);
1161ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1162ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1163ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
1164ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mSession == null) {
1165ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                loge("removeParticipants :: ");
1166ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                throw new ImsException("No call session",
1167ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED);
1168ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1169ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1170ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mSession.removeParticipants(participants);
1171ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1172ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1173ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1174ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1175ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
1176ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Sends a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833</a>,
1177ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15,
1178ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * and event flash to 16. Currently, event flash is not supported.
1179ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
1180ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param code the DTMF to send. Value 0 to 15 (inclusive) are valid inputs.
1181ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
1182ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public void sendDtmf(int code) {
1183ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        sendDtmf(code, null);
1184ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1185ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1186ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
1187ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Sends a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833</a>,
1188ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15,
1189ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * and event flash to 16. Currently, event flash is not supported.
1190ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
1191ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param code the DTMF to send. Value 0 to 15 (inclusive) are valid inputs.
1192ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param result the result message to send when done
1193ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
1194ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public void sendDtmf(int code, Message result) {
1195ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (DBG) {
1196ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            log("sendDtmf :: session=" + mSession + ", code=" + code);
1197ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1198ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1199ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
1200ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mSession != null) {
1201ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mSession.sendDtmf(code);
1202ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1203ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1204ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1205ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (result != null) {
1206ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            result.sendToTarget();
1207ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1208ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1209ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1210ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
1211ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Sends an USSD message.
1212ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     *
1213ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * @param ussdMessage USSD message to send
1214ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
1215ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    public void sendUssd(String ussdMessage) throws ImsException {
1216ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (DBG) {
1217ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            log("sendUssd :: session=" + mSession + ", ussdMessage=" + ussdMessage);
1218ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1219ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1220ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
1221ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mSession == null) {
1222ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                loge("sendUssd :: ");
1223ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                throw new ImsException("No call session",
1224ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED);
1225ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1226ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1227ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mSession.sendUssd(ussdMessage);
1228ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1229ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1230ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1231ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private void clear(ImsReasonInfo lastReasonInfo) {
1232ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        mInCall = false;
1233ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        mHold = false;
1234ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        mUpdateRequest = UPDATE_NONE;
1235ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        mLastReasonInfo = lastReasonInfo;
1236ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        destroyCallGroup();
1237ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1238ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1239ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private void createCallGroup(ImsCall neutralReferrer) {
1240ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        CallGroup referrerCallGroup = neutralReferrer.getCallGroup();
1241ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1242ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (mCallGroup == null) {
1243ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (referrerCallGroup == null) {
1244ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mCallGroup = CallGroupManager.getInstance().createCallGroup(new ImsCallGroup());
1245ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            } else {
1246ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mCallGroup = referrerCallGroup;
1247ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1248ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1249ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mCallGroup != null) {
1250ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mCallGroup.setNeutralReferrer(neutralReferrer);
1251ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1252ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        } else {
1253ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mCallGroup.setNeutralReferrer(neutralReferrer);
1254ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1255ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if ((referrerCallGroup != null)
1256ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    && (mCallGroup != referrerCallGroup)) {
1257ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                loge("fatal :: call group is mismatched; call is corrupted...");
1258ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1259ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1260ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1261ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1262ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private void updateCallGroup(ImsCall owner) {
1263ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (mCallGroup == null) {
1264ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return;
1265ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1266ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1267ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        ImsCall neutralReferrer = (ImsCall)mCallGroup.getNeutralReferrer();
1268ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1269ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        mCallGroup.setNeutralReferrer(null);
1270ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1271ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (owner == null) {
1272ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            // Maintain the call group if the current call has been merged in the past.
1273ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (!mCallGroup.hasReferrer()) {
1274ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                CallGroupManager.getInstance().destroyCallGroup(mCallGroup);
1275ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mCallGroup = null;
1276ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1277ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        } else {
1278ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mCallGroup.addReferrer(this);
1279ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1280ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (neutralReferrer != null) {
1281ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                if (neutralReferrer.isInCall() && (neutralReferrer.getCallGroup() == null)) {
1282ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    neutralReferrer.setCallGroup(mCallGroup);
1283ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    mCallGroup.addReferrer(neutralReferrer);
1284ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1285ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1286ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                neutralReferrer.enforceConversationMode();
1287ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1288ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1289ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            // Close the existing owner call if present
1290ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall exOwner = (ImsCall)mCallGroup.getOwner();
1291ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1292ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mCallGroup.setOwner(owner);
1293ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1294ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (exOwner != null) {
1295ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                exOwner.close();
1296ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1297ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1298ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1299ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1300ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private void destroyCallGroup() {
1301ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (mCallGroup == null) {
1302ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return;
1303ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1304ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1305ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        mCallGroup.removeReferrer(this);
1306ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1307ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (!mCallGroup.hasReferrer()) {
1308ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            CallGroupManager.getInstance().destroyCallGroup(mCallGroup);
1309ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1310ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1311ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        mCallGroup = null;
1312ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1313ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1314ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private CallGroup getCallGroup() {
1315ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
1316ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return mCallGroup;
1317ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1318ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1319ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1320ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private void setCallGroup(CallGroup callGroup) {
1321ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        synchronized(mLockObj) {
1322ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mCallGroup = callGroup;
1323ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1324ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1325ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1326ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    /**
1327ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     * Creates an IMS call session listener.
1328ef36ef67e009449300b0150c60c9f637e205d79eWink Saville     */
1329ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private ImsCallSession.Listener createCallSessionListener() {
1330ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        return new ImsCallSessionListenerProxy();
1331ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1332ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1333ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private ImsCall createNewCall(ImsCallSession session, ImsCallProfile profile) {
1334ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        ImsCall call = new ImsCall(mContext, profile);
1335ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1336ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        try {
1337ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            call.attachSession(session);
1338ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        } catch (ImsException e) {
1339ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (call != null) {
1340ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                call.close();
1341ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                call = null;
1342ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1343ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1344ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1345ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        // Do additional operations...
1346ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1347ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        return call;
1348ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1349ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1350ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private ImsStreamMediaProfile createHoldMediaProfile() {
1351ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        ImsStreamMediaProfile mediaProfile = new ImsStreamMediaProfile();
1352ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1353ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (mCallProfile == null) {
1354ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return mediaProfile;
1355ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1356ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1357ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        mediaProfile.mAudioQuality = mCallProfile.mMediaProfile.mAudioQuality;
1358ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        mediaProfile.mVideoQuality = mCallProfile.mMediaProfile.mVideoQuality;
1359ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        mediaProfile.mAudioDirection = ImsStreamMediaProfile.DIRECTION_SEND;
1360ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1361ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (mediaProfile.mVideoQuality != ImsStreamMediaProfile.VIDEO_QUALITY_NONE) {
1362ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mediaProfile.mVideoDirection = ImsStreamMediaProfile.DIRECTION_SEND;
1363ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1364ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1365ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        return mediaProfile;
1366ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1367ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1368ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private ImsStreamMediaProfile createResumeMediaProfile() {
1369ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        ImsStreamMediaProfile mediaProfile = new ImsStreamMediaProfile();
1370ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1371ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (mCallProfile == null) {
1372ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return mediaProfile;
1373ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1374ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1375ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        mediaProfile.mAudioQuality = mCallProfile.mMediaProfile.mAudioQuality;
1376ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        mediaProfile.mVideoQuality = mCallProfile.mMediaProfile.mVideoQuality;
1377ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        mediaProfile.mAudioDirection = ImsStreamMediaProfile.DIRECTION_SEND_RECEIVE;
1378ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1379ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (mediaProfile.mVideoQuality != ImsStreamMediaProfile.VIDEO_QUALITY_NONE) {
1380ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mediaProfile.mVideoDirection = ImsStreamMediaProfile.DIRECTION_SEND_RECEIVE;
1381ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1382ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1383ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        return mediaProfile;
1384ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1385ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1386ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private void enforceConversationMode() {
1387ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (mInCall) {
1388ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mHold = false;
1389ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mUpdateRequest = UPDATE_NONE;
1390ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1391ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1392ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1393ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private void mergeInternal() {
1394ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (DBG) {
1395ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            log("mergeInternal :: session=" + mSession);
1396ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1397ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1398ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        mSession.merge();
1399ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        mUpdateRequest = UPDATE_MERGE;
1400ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1401ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1402ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private void notifyCallStateChanged() {
1403ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        int state = 0;
1404ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1405ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (mInCall && (mUpdateRequest == UPDATE_HOLD_MERGE)) {
1406ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            state = CALL_STATE_ACTIVE_TO_HOLD;
1407ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mHold = true;
1408ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        } else if (mInCall && ((mUpdateRequest == UPDATE_MERGE)
1409ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                || (mUpdateRequest == UPDATE_EXTEND_TO_CONFERENCE))) {
1410ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            state = CALL_STATE_HOLD_TO_ACTIVE;
1411ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mHold = false;
1412ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            mMute = false;
1413ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1414ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1415ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (state != 0) {
1416ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (mListener != null) {
1417ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
1418ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    mListener.onCallStateChanged(ImsCall.this, state);
1419ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
1420ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("notifyCallStateChanged :: ", t);
1421ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1422ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1423ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1424ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1425ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1426ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private void notifyConferenceSessionTerminated(ImsReasonInfo reasonInfo) {
1427ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        ImsCall.Listener listener;
1428ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1429ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (mCallGroup.isOwner(ImsCall.this)) {
1430ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ArrayList<ICall> referrers = mCallGroup.getReferrers();
1431ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1432ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (referrers != null) {
1433ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                for (int i = 0; i < referrers.size(); ++i) {
1434ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    ImsCall call = (ImsCall)referrers.get(i);
1435ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1436ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    if (call == null) {
1437ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        continue;
1438ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    }
1439ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1440ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener = call.mListener;
1441ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    call.clear(reasonInfo);
1442ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1443ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    if (listener != null) {
1444ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        try {
1445ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                            listener.onCallTerminated(call, reasonInfo);
1446ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        } catch (Throwable t) {
1447ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                            loge("notifyConferenceSessionTerminated :: ", t);
1448ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        }
1449ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    }
1450ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1451ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1452ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        } else if (!mCallGroup.isReferrer(ImsCall.this)) {
1453ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return;
1454ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1455ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1456ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        listener = mListener;
1457ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        clear(reasonInfo);
1458ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1459ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (listener != null) {
1460ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            try {
1461ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener.onCallTerminated(this, reasonInfo);
1462ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            } catch (Throwable t) {
1463ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                loge("notifyConferenceSessionTerminated :: ", t);
1464ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1465ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1466ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1467ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1468ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private void notifyConferenceStateUpdated(ImsConferenceState state) {
1469ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        Set<Entry<String, Bundle>> paticipants = state.mParticipants.entrySet();
1470ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1471ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (paticipants == null) {
1472ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            return;
1473ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1474ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1475ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        Iterator<Entry<String, Bundle>> iterator = paticipants.iterator();
1476ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1477ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        while (iterator.hasNext()) {
1478ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            Entry<String, Bundle> entry = iterator.next();
1479ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1480ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            String key = entry.getKey();
1481ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            Bundle confInfo = entry.getValue();
1482ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            String status = confInfo.getString(ImsConferenceState.STATUS);
1483ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            String user = confInfo.getString(ImsConferenceState.USER);
1484ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            String endpoint = confInfo.getString(ImsConferenceState.ENDPOINT);
1485ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1486ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
1487ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("notifyConferenceStateUpdated :: key=" + key +
1488ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ", status=" + status +
1489ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ", user=" + user +
1490ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ", endpoint=" + endpoint);
1491ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1492ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1493ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if ((mCallGroup != null) && (!mCallGroup.isOwner(ImsCall.this))) {
1494ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                continue;
1495ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1496ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1497ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall referrer = (ImsCall)mCallGroup.getReferrer(endpoint);
1498ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1499ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (referrer == null) {
1500ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                continue;
1501ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1502ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1503ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (referrer.mListener == null) {
1504ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                continue;
1505ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1506ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1507ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            try {
1508ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                if (status.equals(ImsConferenceState.STATUS_ALERTING)) {
1509ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    referrer.mListener.onCallProgressing(referrer);
1510ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1511ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                else if (status.equals(ImsConferenceState.STATUS_CONNECT_FAIL)) {
1512ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    referrer.mListener.onCallStartFailed(referrer, new ImsReasonInfo());
1513ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1514ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                else if (status.equals(ImsConferenceState.STATUS_ON_HOLD)) {
1515ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    referrer.mListener.onCallHoldReceived(referrer);
1516ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1517ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                else if (status.equals(ImsConferenceState.STATUS_CONNECTED)) {
1518ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    referrer.mListener.onCallStarted(referrer);
1519ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1520ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                else if (status.equals(ImsConferenceState.STATUS_DISCONNECTED)) {
1521ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    referrer.clear(new ImsReasonInfo());
1522ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    referrer.mListener.onCallTerminated(referrer, referrer.mLastReasonInfo);
1523ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1524ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            } catch (Throwable t) {
1525ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                loge("notifyConferenceStateUpdated :: ", t);
1526ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1527ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1528ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1529ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1530ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private void notifyError(int reason, int statusCode, String message) {
1531ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1532ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1533ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private void throwImsException(Throwable t, int code) throws ImsException {
1534ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        if (t instanceof ImsException) {
1535ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            throw (ImsException) t;
1536ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        } else {
1537ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            throw new ImsException(String.valueOf(code), t, code);
1538ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1539ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1540ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1541ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private void log(String s) {
1542ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        Rlog.d(TAG, s);
1543ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1544ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1545ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private void loge(String s) {
1546ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        Rlog.e(TAG, s);
1547ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1548ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1549ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private void loge(String s, Throwable t) {
1550ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        Rlog.e(TAG, s, t);
1551ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
1552ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1553ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    private class ImsCallSessionListenerProxy extends ImsCallSession.Listener {
1554ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
1555ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionProgressing(ImsCallSession session,
1556ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsStreamMediaProfile profile) {
1557ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
1558ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionProgressing :: session=" + session + ", profile=" + profile);
1559ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1560ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1561ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
1562ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1563ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
1564ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
1565ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mCallProfile.mMediaProfile.copyFrom(profile);
1566ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1567ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1568ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
1569ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
1570ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallProgressing(ImsCall.this);
1571ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
1572ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionProgressing :: ", t);
1573ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1574ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1575ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1576ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1577ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
1578ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionStarted(ImsCallSession session,
1579ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsCallProfile profile) {
1580ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
1581ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionStarted :: session=" + session + ", profile=" + profile);
1582ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1583ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1584ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
1585ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1586ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
1587ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
1588ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mCallProfile = profile;
1589ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1590ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1591ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
1592ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
1593ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallStarted(ImsCall.this);
1594ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
1595ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionStarted :: ", t);
1596ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1597ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1598ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1599ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1600ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
1601ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionStartFailed(ImsCallSession session,
1602ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsReasonInfo reasonInfo) {
1603ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
1604ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionStartFailed :: session=" + session +
1605ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ", reasonInfo=" + reasonInfo);
1606ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1607ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1608ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
1609ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1610ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
1611ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
1612ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mLastReasonInfo = reasonInfo;
1613ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1614ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1615ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
1616ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
1617ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallStartFailed(ImsCall.this, reasonInfo);
1618ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
1619ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionStarted :: ", t);
1620ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1621ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1622ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1623ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1624ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
1625ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionTerminated(ImsCallSession session,
1626ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsReasonInfo reasonInfo) {
1627ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
1628ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionTerminated :: session=" + session +
1629ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ", reasonInfo=" + reasonInfo);
1630ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1631ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1632ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener = null;
1633ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1634ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
1635ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                if (mCallGroup != null) {
1636ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    notifyConferenceSessionTerminated(reasonInfo);
1637ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } else {
1638ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener = mListener;
1639ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    clear(reasonInfo);
1640ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1641ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1642ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1643ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
1644ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
1645ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallTerminated(ImsCall.this, reasonInfo);
1646ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
1647ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionTerminated :: ", t);
1648ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1649ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1650ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1651ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1652ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
1653ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionHeld(ImsCallSession session,
1654ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsCallProfile profile) {
1655ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
1656ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionHeld :: session=" + session + ", profile=" + profile);
1657ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1658ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1659ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
1660ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1661ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
1662ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mCallProfile = profile;
1663ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1664ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                if (mUpdateRequest == UPDATE_HOLD_MERGE) {
1665ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    mergeInternal();
1666ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    return;
1667ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1668ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1669ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mUpdateRequest = UPDATE_NONE;
1670ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
1671ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1672ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1673ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
1674ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
1675ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallHeld(ImsCall.this);
1676ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
1677ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionHeld :: ", t);
1678ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1679ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1680ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1681ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1682ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
1683ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionHoldFailed(ImsCallSession session,
1684ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsReasonInfo reasonInfo) {
1685ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
1686ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionHoldFailed :: session=" + session +
1687ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ", reasonInfo=" + reasonInfo);
1688ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1689ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1690ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            boolean isHoldForMerge = false;
1691ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
1692ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1693ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
1694ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                if (mUpdateRequest == UPDATE_HOLD_MERGE) {
1695ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    isHoldForMerge = true;
1696ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1697ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1698ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mUpdateRequest = UPDATE_NONE;
1699ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
1700ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1701ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1702ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (isHoldForMerge) {
1703ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                callSessionMergeFailed(session, reasonInfo);
1704ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                return;
1705ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1706ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1707ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
1708ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
1709ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallHoldFailed(ImsCall.this, reasonInfo);
1710ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
1711ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionHoldFailed :: ", t);
1712ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1713ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1714ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1715ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1716ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
1717ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionHoldReceived(ImsCallSession session,
1718ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsCallProfile profile) {
1719ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
1720ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionHoldReceived :: session=" + session + ", profile=" + profile);
1721ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1722ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1723ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
1724ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1725ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
1726ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
1727ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mCallProfile = profile;
1728ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1729ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1730ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
1731ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
1732ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallHoldReceived(ImsCall.this);
1733ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
1734ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionHoldReceived :: ", t);
1735ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1736ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1737ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1738ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1739ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
1740ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionResumed(ImsCallSession session,
1741ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsCallProfile profile) {
1742ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
1743ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionResumed :: session=" + session + ", profile=" + profile);
1744ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1745ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1746ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
1747ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1748ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
1749ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
1750ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mCallProfile = profile;
1751ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mUpdateRequest = UPDATE_NONE;
1752ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1753ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1754ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
1755ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
1756ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallResumed(ImsCall.this);
1757ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
1758ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionResumed :: ", t);
1759ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1760ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1761ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1762ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1763ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
1764ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionResumeFailed(ImsCallSession session,
1765ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsReasonInfo reasonInfo) {
1766ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
1767ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionResumeFailed :: session=" + session +
1768ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ", reasonInfo=" + reasonInfo);
1769ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1770ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1771ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
1772ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1773ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
1774ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
1775ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mUpdateRequest = UPDATE_NONE;
1776ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1777ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1778ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
1779ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
1780ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallResumeFailed(ImsCall.this, reasonInfo);
1781ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
1782ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionResumeFailed :: ", t);
1783ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1784ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1785ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1786ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1787ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
1788ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionResumeReceived(ImsCallSession session,
1789ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsCallProfile profile) {
1790ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
1791ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionResumeReceived :: session=" + session +
1792ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ", profile=" + profile);
1793ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1794ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1795ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
1796ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1797ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
1798ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
1799ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mCallProfile = profile;
1800ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1801ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1802ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
1803ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
1804ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallResumeReceived(ImsCall.this);
1805ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
1806ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionResumeReceived :: ", t);
1807ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1808ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1809ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1810ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1811ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
1812ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionMerged(ImsCallSession session,
1813ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsCallSession newSession, ImsCallProfile profile) {
1814ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
1815ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionMerged :: session=" + session
1816ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        + ", newSession=" + newSession + ", profile=" + profile);
1817ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1818ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1819ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall newCall = createNewCall(newSession, profile);
1820ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1821ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (newCall == null) {
1822ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                callSessionMergeFailed(session, new ImsReasonInfo());
1823ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                return;
1824ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1825ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1826ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
1827ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1828ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
1829ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
1830ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                updateCallGroup(newCall);
1831ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mUpdateRequest = UPDATE_NONE;
1832ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1833ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1834ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
1835ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
1836ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallMerged(ImsCall.this, newCall);
1837ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
1838ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionMerged :: ", t);
1839ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1840ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1841ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1842ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1843ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
1844ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionMergeFailed(ImsCallSession session,
1845ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsReasonInfo reasonInfo) {
1846ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
1847ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionMergeFailed :: session=" + session +
1848ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ", reasonInfo=" + reasonInfo);
1849ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1850ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1851ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
1852ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1853ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
1854ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
1855ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                updateCallGroup(null);
1856ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mUpdateRequest = UPDATE_NONE;
1857ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1858ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1859ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
1860ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
1861ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallMergeFailed(ImsCall.this, reasonInfo);
1862ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
1863ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionMergeFailed :: ", t);
1864ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1865ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1866ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1867ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1868ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
1869ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionUpdated(ImsCallSession session,
1870ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsCallProfile profile) {
1871ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
1872ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionUpdated :: session=" + session + ", profile=" + profile);
1873ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1874ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1875ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
1876ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1877ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
1878ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
1879ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mCallProfile = profile;
1880ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mUpdateRequest = UPDATE_NONE;
1881ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1882ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1883ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
1884ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
1885ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallUpdated(ImsCall.this);
1886ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
1887ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionUpdated :: ", t);
1888ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1889ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1890ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1891ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1892ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
1893ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionUpdateFailed(ImsCallSession session,
1894ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsReasonInfo reasonInfo) {
1895ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
1896ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionUpdateFailed :: session=" + session +
1897ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ", reasonInfo=" + reasonInfo);
1898ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1899ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1900ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
1901ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1902ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
1903ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
1904ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mUpdateRequest = UPDATE_NONE;
1905ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1906ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1907ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
1908ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
1909ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallUpdateFailed(ImsCall.this, reasonInfo);
1910ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
1911ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionUpdateFailed :: ", t);
1912ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1913ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1914ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1915ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1916ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
1917ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionUpdateReceived(ImsCallSession session,
1918ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsCallProfile profile) {
1919ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
1920ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionUpdateReceived :: session=" + session +
1921ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ", profile=" + profile);
1922ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1923ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1924ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
1925ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1926ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
1927ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
1928ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mProposedCallProfile = profile;
1929ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mUpdateRequest = UPDATE_UNSPECIFIED;
1930ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1931ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1932ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
1933ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
1934ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallUpdateReceived(ImsCall.this);
1935ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
1936ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionUpdateReceived :: ", t);
1937ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1938ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1939ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1940ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1941ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
1942ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionConferenceExtended(ImsCallSession session,
1943ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsCallSession newSession, ImsCallProfile profile) {
1944ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
1945ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionConferenceExtended :: session=" + session
1946ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        + ", newSession=" + newSession + ", profile=" + profile);
1947ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1948ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1949ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall newCall = createNewCall(newSession, profile);
1950ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1951ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (newCall == null) {
1952ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                callSessionConferenceExtendFailed(session, new ImsReasonInfo());
1953ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                return;
1954ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1955ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1956ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
1957ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1958ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
1959ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
1960ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mUpdateRequest = UPDATE_NONE;
1961ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1962ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1963ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
1964ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
1965ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallConferenceExtended(ImsCall.this, newCall);
1966ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
1967ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionConferenceExtended :: ", t);
1968ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1969ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1970ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1971ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1972ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
1973ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionConferenceExtendFailed(ImsCallSession session,
1974ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsReasonInfo reasonInfo) {
1975ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
1976ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionConferenceExtendFailed :: session=" + session +
1977ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        ", reasonInfo=" + reasonInfo);
1978ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1979ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1980ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
1981ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1982ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
1983ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
1984ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                mUpdateRequest = UPDATE_NONE;
1985ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1986ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1987ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
1988ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
1989ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallConferenceExtendFailed(ImsCall.this, reasonInfo);
1990ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
1991ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionConferenceExtendFailed :: ", t);
1992ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
1993ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
1994ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
1995ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
1996ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
1997ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionConferenceExtendReceived(ImsCallSession session,
1998ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsCallSession newSession, ImsCallProfile profile) {
1999ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
2000ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionConferenceExtendReceived :: session=" + session
2001ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        + ", newSession=" + newSession + ", profile=" + profile);
2002ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2003ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2004ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall newCall = createNewCall(newSession, profile);
2005ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2006ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (newCall == null) {
2007ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                // Should all the calls be terminated...???
2008ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                return;
2009ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2010ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2011ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
2012ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2013ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
2014ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
2015ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2016ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2017ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
2018ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
2019ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallConferenceExtendReceived(ImsCall.this, newCall);
2020ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
2021ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionConferenceExtendReceived :: ", t);
2022ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
2023ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2024ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
2025ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2026ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
2027ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionInviteParticipantsRequestDelivered(ImsCallSession session) {
2028ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
2029ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionInviteParticipantsRequestDelivered :: session=" + session);
2030ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2031ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2032ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
2033ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2034ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
2035ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
2036ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2037ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2038ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
2039ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
2040ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallInviteParticipantsRequestDelivered(ImsCall.this);
2041ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
2042ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionInviteParticipantsRequestDelivered :: ", t);
2043ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
2044ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2045ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
2046ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2047ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
2048ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionInviteParticipantsRequestFailed(ImsCallSession session,
2049ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsReasonInfo reasonInfo) {
2050ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
2051ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionInviteParticipantsRequestFailed :: session=" + session
2052ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        + ", reasonInfo=" + reasonInfo);
2053ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2054ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2055ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
2056ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2057ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
2058ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
2059ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2060ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2061ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
2062ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
2063ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallInviteParticipantsRequestFailed(ImsCall.this, reasonInfo);
2064ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
2065ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionInviteParticipantsRequestFailed :: ", t);
2066ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
2067ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2068ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
2069ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2070ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
2071ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionRemoveParticipantsRequestDelivered(ImsCallSession session) {
2072ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
2073ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionRemoveParticipantsRequestDelivered :: session=" + session);
2074ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2075ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2076ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
2077ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2078ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
2079ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
2080ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2081ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2082ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
2083ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
2084ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallRemoveParticipantsRequestDelivered(ImsCall.this);
2085ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
2086ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionRemoveParticipantsRequestDelivered :: ", t);
2087ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
2088ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2089ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
2090ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2091ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
2092ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionRemoveParticipantsRequestFailed(ImsCallSession session,
2093ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsReasonInfo reasonInfo) {
2094ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
2095ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionRemoveParticipantsRequestFailed :: session=" + session
2096ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        + ", reasonInfo=" + reasonInfo);
2097ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2098ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2099ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
2100ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2101ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
2102ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
2103ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2104ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2105ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
2106ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
2107ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallRemoveParticipantsRequestFailed(ImsCall.this, reasonInfo);
2108ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
2109ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionRemoveParticipantsRequestFailed :: ", t);
2110ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
2111ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2112ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
2113ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2114ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
2115ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionConferenceStateUpdated(ImsCallSession session,
2116ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                ImsConferenceState state) {
2117ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
2118ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionConferenceStateUpdated :: session=" + session
2119ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        + ", state=" + state);
2120ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2121ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2122ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
2123ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2124ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
2125ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                notifyConferenceStateUpdated(state);
2126ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
2127ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2128ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2129ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
2130ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
2131ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallConferenceStateUpdated(ImsCall.this, state);
2132ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
2133ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionConferenceStateUpdated :: ", t);
2134ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
2135ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2136ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
2137ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2138ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        @Override
2139ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        public void callSessionUssdMessageReceived(ImsCallSession session,
2140ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                int mode, String ussdMessage) {
2141ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (DBG) {
2142ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                log("callSessionUssdMessageReceived :: session=" + session
2143ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                        + ", mode=" + mode + ", ussdMessage=" + ussdMessage);
2144ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2145ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2146ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            ImsCall.Listener listener;
2147ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2148ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            synchronized(ImsCall.this) {
2149ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                listener = mListener;
2150ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2151ef36ef67e009449300b0150c60c9f637e205d79eWink Saville
2152ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            if (listener != null) {
2153ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                try {
2154ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    listener.onCallUssdMessageReceived(ImsCall.this, mode, ussdMessage);
2155ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                } catch (Throwable t) {
2156ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                    loge("callSessionUssdMessageReceived :: ", t);
2157ef36ef67e009449300b0150c60c9f637e205d79eWink Saville                }
2158ef36ef67e009449300b0150c60c9f637e205d79eWink Saville            }
2159ef36ef67e009449300b0150c60c9f637e205d79eWink Saville        }
2160ef36ef67e009449300b0150c60c9f637e205d79eWink Saville    }
2161ef36ef67e009449300b0150c60c9f637e205d79eWink Saville}
2162