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 211c46760f9e523312d92e027dfdb52d359d65efe1Tyler Gunnimport java.util.ArrayList; 22ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport java.util.Iterator; 231c46760f9e523312d92e027dfdb52d359d65efe1Tyler Gunnimport java.util.List; 24ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport java.util.Map.Entry; 25ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport java.util.Set; 26ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 27ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport android.content.Context; 285965614f5b813f2739722589f84cec69c572b0a2Tyler Gunnimport android.net.Uri; 29ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport android.os.Bundle; 30ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport android.os.Message; 315965614f5b813f2739722589f84cec69c572b0a2Tyler Gunnimport android.telecom.ConferenceParticipant; 325aec2e957365f20b2e75d3b8c7034e3289729b81Rekha Kumarimport android.telecom.Connection; 3395be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingamimport java.util.Objects; 349bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunnimport android.util.Log; 35ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 36ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport com.android.ims.internal.ICall; 37ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport com.android.ims.internal.ImsCallSession; 38ef36ef67e009449300b0150c60c9f637e205d79eWink Savilleimport com.android.ims.internal.ImsStreamMediaSession; 39938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunnimport com.android.internal.annotations.VisibleForTesting; 40ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 41ef36ef67e009449300b0150c60c9f637e205d79eWink Saville/** 42ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Handles an IMS voice / video call over LTE. You can instantiate this class with 43ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * {@link ImsManager}. 44ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 45ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @hide 46ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 47ef36ef67e009449300b0150c60c9f637e205d79eWink Savillepublic class ImsCall implements ICall { 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"; 536804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 546804851b58264d7e82b09a845118d24d36c8d831Anthony Lee // This flag is meant to be used as a debugging tool to quickly see all logs 556804851b58264d7e82b09a845118d24d36c8d831Anthony Lee // regardless of the actual log level set on this component. 566cb99be298f8b1b4363fdacc1cc631c3671380ecTyler Gunn private static final boolean FORCE_DEBUG = false; /* STOPSHIP if true */ 576804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 586804851b58264d7e82b09a845118d24d36c8d831Anthony Lee // We will log messages guarded by these flags at the info level. If logging is required 596804851b58264d7e82b09a845118d24d36c8d831Anthony Lee // to occur at (and only at) a particular log level, please use the logd, logv and loge 606804851b58264d7e82b09a845118d24d36c8d831Anthony Lee // functions as those will not be affected by the value of FORCE_DEBUG at all. 616804851b58264d7e82b09a845118d24d36c8d831Anthony Lee // Otherwise, anything guarded by these flags will be logged at the info level since that 626804851b58264d7e82b09a845118d24d36c8d831Anthony Lee // level allows those statements ot be logged by default which supports the workflow of 636804851b58264d7e82b09a845118d24d36c8d831Anthony Lee // setting FORCE_DEBUG and knowing these logs will show up regardless of the actual log 646804851b58264d7e82b09a845118d24d36c8d831Anthony Lee // level of this component. 656804851b58264d7e82b09a845118d24d36c8d831Anthony Lee private static final boolean DBG = FORCE_DEBUG || Log.isLoggable(TAG, Log.DEBUG); 666804851b58264d7e82b09a845118d24d36c8d831Anthony Lee private static final boolean VDBG = FORCE_DEBUG || Log.isLoggable(TAG, Log.VERBOSE); 676804851b58264d7e82b09a845118d24d36c8d831Anthony Lee // This is a special flag that is used only to highlight specific log around bringing 686804851b58264d7e82b09a845118d24d36c8d831Anthony Lee // up and tearing down conference calls. At times, these errors are transient and hard to 696804851b58264d7e82b09a845118d24d36c8d831Anthony Lee // reproduce so we need to capture this information the first time. 706804851b58264d7e82b09a845118d24d36c8d831Anthony Lee // TODO: Set this flag to FORCE_DEBUG once the new conference call logic gets more mileage 716804851b58264d7e82b09a845118d24d36c8d831Anthony Lee // across different IMS implementations. 726804851b58264d7e82b09a845118d24d36c8d831Anthony Lee private static final boolean CONF_DBG = true; 73ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 74a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam private List<ConferenceParticipant> mConferenceParticipants; 75ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 76ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Listener for events relating to an IMS call, such as when a call is being 77c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee * received ("on ringing") or a call is outgoing ("on calling"). 78ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * <p>Many of these events are also received by {@link ImsCallSession.Listener}.</p> 79ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 80ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public static class Listener { 81ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 82ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when a request is sent out to initiate a new call 83ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * and 1xx response is received from the network. 84ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * The default implementation calls {@link #onCallStateChanged}. 85ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 86ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 87ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 88ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallProgressing(ImsCall call) { 89ef36ef67e009449300b0150c60c9f637e205d79eWink Saville onCallStateChanged(call); 90ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 91ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 92ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 93ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the call is established. 94ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * The default implementation calls {@link #onCallStateChanged}. 95ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 96ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 97ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 98ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallStarted(ImsCall call) { 99ef36ef67e009449300b0150c60c9f637e205d79eWink Saville onCallStateChanged(call); 100ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 101ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 102ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 103ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the call setup is failed. 104ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * The default implementation calls {@link #onCallError}. 105ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 106ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 107ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param reasonInfo detailed reason of the call setup failure 108ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 109ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallStartFailed(ImsCall call, ImsReasonInfo reasonInfo) { 110ef36ef67e009449300b0150c60c9f637e205d79eWink Saville onCallError(call, reasonInfo); 111ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 112ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 113ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 114ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the call is terminated. 115ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * The default implementation calls {@link #onCallStateChanged}. 116ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 117ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 118ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param reasonInfo detailed reason of the call termination 119ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 120ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallTerminated(ImsCall call, ImsReasonInfo reasonInfo) { 121ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // Store the call termination reason 122ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 123ef36ef67e009449300b0150c60c9f637e205d79eWink Saville onCallStateChanged(call); 124ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 125ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 126ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 127ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the call is in hold. 128ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * The default implementation calls {@link #onCallStateChanged}. 129ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 130ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 131ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 132ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallHeld(ImsCall call) { 133ef36ef67e009449300b0150c60c9f637e205d79eWink Saville onCallStateChanged(call); 134ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 135ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 136ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 137ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the call hold is failed. 138ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * The default implementation calls {@link #onCallError}. 139ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 140ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 141ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param reasonInfo detailed reason of the call hold failure 142ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 143ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallHoldFailed(ImsCall call, ImsReasonInfo reasonInfo) { 144ef36ef67e009449300b0150c60c9f637e205d79eWink Saville onCallError(call, reasonInfo); 145ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 146ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 147ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 148ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the call hold is received from the remote user. 149ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * The default implementation calls {@link #onCallStateChanged}. 150ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 151ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 152ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 153ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallHoldReceived(ImsCall call) { 154ef36ef67e009449300b0150c60c9f637e205d79eWink Saville onCallStateChanged(call); 155ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 156ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 157ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 158ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the call is in call. 159ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * The default implementation calls {@link #onCallStateChanged}. 160ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 161ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 162ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 163ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallResumed(ImsCall call) { 164ef36ef67e009449300b0150c60c9f637e205d79eWink Saville onCallStateChanged(call); 165ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 166ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 167ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 168ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the call resume is failed. 169ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * The default implementation calls {@link #onCallError}. 170ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 171ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 172ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param reasonInfo detailed reason of the call resume failure 173ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 174ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallResumeFailed(ImsCall call, ImsReasonInfo reasonInfo) { 175ef36ef67e009449300b0150c60c9f637e205d79eWink Saville onCallError(call, reasonInfo); 176ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 177ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 178ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 179ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the call resume is received from the remote user. 180ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * The default implementation calls {@link #onCallStateChanged}. 181ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 182ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 183ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 184ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallResumeReceived(ImsCall call) { 185ef36ef67e009449300b0150c60c9f637e205d79eWink Saville onCallStateChanged(call); 186ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 187ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 188ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 189ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the call is in call. 190ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * The default implementation calls {@link #onCallStateChanged}. 191ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 19295be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * @param call the call object that carries out the active IMS call 19395be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * @param peerCall the call object that carries out the held IMS call 194047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn * @param swapCalls {@code true} if the foreground and background calls should be swapped 195047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn * now that the merge has completed. 196ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 19795be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam public void onCallMerged(ImsCall call, ImsCall peerCall, boolean swapCalls) { 19871382693cbc81b1d131085f52d97879976706f55Anthony Lee onCallStateChanged(call); 199ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 200ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 201ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 202ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the call merge is failed. 203ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * The default implementation calls {@link #onCallError}. 204ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 205ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 206ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param reasonInfo detailed reason of the call merge failure 207ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 208ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallMergeFailed(ImsCall call, ImsReasonInfo reasonInfo) { 209ef36ef67e009449300b0150c60c9f637e205d79eWink Saville onCallError(call, reasonInfo); 210ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 211ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 212ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 213ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the call is updated (except for hold/unhold). 214ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * The default implementation calls {@link #onCallStateChanged}. 215ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 216ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 217ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 218ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallUpdated(ImsCall call) { 219ef36ef67e009449300b0150c60c9f637e205d79eWink Saville onCallStateChanged(call); 220ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 221ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 222ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 223ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the call update is failed. 224ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * The default implementation calls {@link #onCallError}. 225ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 226ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 227ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param reasonInfo detailed reason of the call update failure 228ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 229ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallUpdateFailed(ImsCall call, ImsReasonInfo reasonInfo) { 230ef36ef67e009449300b0150c60c9f637e205d79eWink Saville onCallError(call, reasonInfo); 231ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 232ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 233ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 234ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the call update is received from the remote user. 235ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 236ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 237ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 238ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallUpdateReceived(ImsCall call) { 239ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // no-op 240ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 241ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 242ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 243ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the call is extended to the conference call. 244ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * The default implementation calls {@link #onCallStateChanged}. 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 onCallConferenceExtended(ImsCall call, ImsCall newCall) { 25071382693cbc81b1d131085f52d97879976706f55Anthony Lee onCallStateChanged(call); 251ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 252ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 253ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 254ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the conference extension is failed. 255ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * The default implementation calls {@link #onCallError}. 256ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 257ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 258ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param reasonInfo detailed reason of the conference extension failure 259ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 260ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallConferenceExtendFailed(ImsCall call, 261ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo reasonInfo) { 262ef36ef67e009449300b0150c60c9f637e205d79eWink Saville onCallError(call, reasonInfo); 263ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 264ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 265ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 266ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the conference extension is received from the remote user. 267ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 268ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 269ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param newCall the call object that is extended to the conference from the active call 270ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 271ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallConferenceExtendReceived(ImsCall call, ImsCall newCall) { 27271382693cbc81b1d131085f52d97879976706f55Anthony Lee onCallStateChanged(call); 273ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 274ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 275ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 276ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the invitation request of the participants is delivered to 277ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * the conference server. 278ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 279ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 280ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 281ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallInviteParticipantsRequestDelivered(ImsCall call) { 282ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // no-op 283ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 284ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 285ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 286ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the invitation request of the participants is failed. 287ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 288ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 289ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param reasonInfo detailed reason of the conference invitation failure 290ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 291ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallInviteParticipantsRequestFailed(ImsCall call, 292ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo reasonInfo) { 293ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // no-op 294ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 295ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 296ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 297ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the removal request of the participants is delivered to 298ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * the conference server. 299ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 300ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 301ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 302ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallRemoveParticipantsRequestDelivered(ImsCall call) { 303ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // no-op 304ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 305ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 306ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 307ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the removal request of the participants is failed. 308ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 309ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 310ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param reasonInfo detailed reason of the conference removal failure 311ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 312ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallRemoveParticipantsRequestFailed(ImsCall call, 313ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo reasonInfo) { 314ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // no-op 315ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 316ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 317ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 318ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the conference state is updated. 319ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 320ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 321ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param state state of the participant who is participated in the conference call 322ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 323ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallConferenceStateUpdated(ImsCall call, ImsConferenceState state) { 324ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // no-op 325ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 326ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 327ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 3281c46760f9e523312d92e027dfdb52d359d65efe1Tyler Gunn * Called when the state of IMS conference participant(s) has changed. 3295965614f5b813f2739722589f84cec69c572b0a2Tyler Gunn * 3305965614f5b813f2739722589f84cec69c572b0a2Tyler Gunn * @param call the call object that carries out the IMS call. 3311c46760f9e523312d92e027dfdb52d359d65efe1Tyler Gunn * @param participants the participant(s) and their new state information. 3325965614f5b813f2739722589f84cec69c572b0a2Tyler Gunn */ 3331c46760f9e523312d92e027dfdb52d359d65efe1Tyler Gunn public void onConferenceParticipantsStateChanged(ImsCall call, 3341c46760f9e523312d92e027dfdb52d359d65efe1Tyler Gunn List<ConferenceParticipant> participants) { 3355965614f5b813f2739722589f84cec69c572b0a2Tyler Gunn // no-op 3365965614f5b813f2739722589f84cec69c572b0a2Tyler Gunn } 3375965614f5b813f2739722589f84cec69c572b0a2Tyler Gunn 3385965614f5b813f2739722589f84cec69c572b0a2Tyler Gunn /** 339ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the USSD message is received from the network. 340ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 341ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param mode mode of the USSD message (REQUEST / NOTIFY) 342ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param ussdMessage USSD message 343ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 344ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallUssdMessageReceived(ImsCall call, 345ef36ef67e009449300b0150c60c9f637e205d79eWink Saville int mode, String ussdMessage) { 346ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // no-op 347ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 348ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 349ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 350ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when an error occurs. The default implementation is no op. 351ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * overridden. The default implementation is no op. Error events are 352ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * not re-directed to this callback and are handled in {@link #onCallError}. 353ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 354ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 355ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param reasonInfo detailed reason of this error 356ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @see ImsReasonInfo 357ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 358ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallError(ImsCall call, ImsReasonInfo reasonInfo) { 359ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // no-op 360ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 361ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 362ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 363ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when an event occurs and the corresponding callback is not 364ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * overridden. The default implementation is no op. Error events are 365ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * not re-directed to this callback and are handled in {@link #onCallError}. 366ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 367ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 368ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 369ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallStateChanged(ImsCall call) { 370ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // no-op 371ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 372ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 373ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 374ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Called when the call moves the hold state to the conversation state. 375ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * For example, when merging the active & hold call, the state of all the hold call 376ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * will be changed from hold state to conversation state. 377ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * This callback method can be invoked even though the application does not trigger 378ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * any operations. 379ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 380ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call object that carries out the IMS call 381ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param state the detailed state of call state changes; 382ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Refer to CALL_STATE_* in {@link ImsCall} 383ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 384ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void onCallStateChanged(ImsCall call, int state) { 385ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // no-op 386ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 387a6cae36b881e26fa288a83c94b8c357fd436140ePavel Zhamaitsiak 388a6cae36b881e26fa288a83c94b8c357fd436140ePavel Zhamaitsiak /** 389d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh * Called when the call supp service is received 390d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh * The default implementation calls {@link #onCallStateChanged}. 391d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh * 392d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh * @param call the call object that carries out the IMS call 393d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh */ 394d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh public void onCallSuppServiceReceived(ImsCall call, 395d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh ImsSuppServiceNotification suppServiceInfo) { 396d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh } 397d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh 398d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh /** 399a6cae36b881e26fa288a83c94b8c357fd436140ePavel Zhamaitsiak * Called when TTY mode of remote party changed 400a6cae36b881e26fa288a83c94b8c357fd436140ePavel Zhamaitsiak * 401a6cae36b881e26fa288a83c94b8c357fd436140ePavel Zhamaitsiak * @param call the call object that carries out the IMS call 402a6cae36b881e26fa288a83c94b8c357fd436140ePavel Zhamaitsiak * @param mode TTY mode of remote party 403a6cae36b881e26fa288a83c94b8c357fd436140ePavel Zhamaitsiak */ 404a6cae36b881e26fa288a83c94b8c357fd436140ePavel Zhamaitsiak public void onCallSessionTtyModeReceived(ImsCall call, int mode) { 405a6cae36b881e26fa288a83c94b8c357fd436140ePavel Zhamaitsiak // no-op 406a6cae36b881e26fa288a83c94b8c357fd436140ePavel Zhamaitsiak } 4071463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar 4081463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar /** 4091463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar * Called when handover occurs from one access technology to another. 4101463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar * 4116804851b58264d7e82b09a845118d24d36c8d831Anthony Lee * @param imsCall ImsCall object 4121463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar * @param srcAccessTech original access technology 4131463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar * @param targetAccessTech new access technology 4141463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar * @param reasonInfo 4151463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar */ 4161463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar public void onCallHandover(ImsCall imsCall, int srcAccessTech, int targetAccessTech, 4171463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar ImsReasonInfo reasonInfo) { 4181463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar } 4191463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar 4201463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar /** 4211463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar * Called when handover from one access technology to another fails. 4221463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar * 4236804851b58264d7e82b09a845118d24d36c8d831Anthony Lee * @param imsCall call that failed the handover. 4241463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar * @param srcAccessTech original access technology 4251463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar * @param targetAccessTech new access technology 4261463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar * @param reasonInfo 4271463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar */ 4281463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar public void onCallHandoverFailed(ImsCall imsCall, int srcAccessTech, int targetAccessTech, 4291463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar ImsReasonInfo reasonInfo) { 4301463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar } 43125394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn 43225394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn /** 43325394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * Notifies of a change to the multiparty state for this {@code ImsCall}. 43425394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * 43525394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * @param imsCall The IMS call. 43625394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * @param isMultiParty {@code true} if the call became multiparty, {@code false} 43725394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * otherwise. 43825394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn */ 43925394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn public void onMultipartyStateChanged(ImsCall imsCall, boolean isMultiParty) { 44025394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn } 441ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 442ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 443ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // List of update operation for IMS call control 444ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private static final int UPDATE_NONE = 0; 445ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private static final int UPDATE_HOLD = 1; 446ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private static final int UPDATE_HOLD_MERGE = 2; 447ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private static final int UPDATE_RESUME = 3; 448ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private static final int UPDATE_MERGE = 4; 449ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private static final int UPDATE_EXTEND_TO_CONFERENCE = 5; 450ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private static final int UPDATE_UNSPECIFIED = 6; 451ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 452ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // For synchronization of private variables 453ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private Object mLockObj = new Object(); 454ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private Context mContext; 455ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 456ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // true if the call is established & in the conversation state 457ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private boolean mInCall = false; 458ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // true if the call is on hold 459ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // If it is triggered by the local, mute the call. Otherwise, play local hold tone 460ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // or network generated media. 461ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private boolean mHold = false; 462ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // true if the call is on mute 463ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private boolean mMute = false; 464ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // It contains the exclusive call update request. Refer to UPDATE_*. 465ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private int mUpdateRequest = UPDATE_NONE; 466ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 467ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private ImsCall.Listener mListener = null; 4689bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn 4699bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn // When merging two calls together, the "peer" call that will merge into this call. 4709bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn private ImsCall mMergePeer = null; 4719bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn // When merging two calls together, the "host" call we are merging into. 4729bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn private ImsCall mMergeHost = null; 473ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 47495be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam // True if Conference request was initiated by 47595be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam // Foreground Conference call else it will be false 47695be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam private boolean mMergeRequestedByConference = false; 477ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // Wrapper call session to interworking the IMS service (server). 478ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private ImsCallSession mSession = null; 479ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // Call profile of the current session. 480ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // It can be changed at anytime when the call is updated. 481ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private ImsCallProfile mCallProfile = null; 482ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // Call profile to be updated after the application's action (accept/reject) 483ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // to the call update. After the application's action (accept/reject) is done, 484ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // it will be set to null. 485ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private ImsCallProfile mProposedCallProfile = null; 486ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private ImsReasonInfo mLastReasonInfo = null; 487ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 488ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // Media session to control media (audio/video) operations for an IMS call 489ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private ImsStreamMediaSession mMediaSession = null; 490ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 491b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee // The temporary ImsCallSession that could represent the merged call once 492b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee // we receive notification that the merge was successful. 49371382693cbc81b1d131085f52d97879976706f55Anthony Lee private ImsCallSession mTransientConferenceSession = null; 494b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee // While a merge is progressing, we bury any session termination requests 495b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee // made on the original ImsCallSession until we have closure on the merge request 496b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee // If the request ultimately fails, we need to act on the termination request 497b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee // that we buried temporarily. We do this because we feel that timing issues could 498b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee // cause the termination request to occur just because the merge is succeeding. 499b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee private boolean mSessionEndDuringMerge = false; 500b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee // Just like mSessionEndDuringMerge, we need to keep track of the reason why the 501b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee // termination request was made on the original session in case we need to act 502b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee // on it in the case of a merge failure. 503b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee private ImsReasonInfo mSessionEndDuringMergeReasonInfo = null; 504c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // This flag is used to indicate if this ImsCall was merged into a conference 505c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // or not. It is used primarily to determine if a disconnect sound should 506c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // be heard when the call is terminated. 5078ae59492156d9cef275f559c5ee09a44315989beAndrew Lee private boolean mIsMerged = false; 508c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // If true, this flag means that this ImsCall is in the process of merging 509c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // into a conference but it does not yet have closure on if it was 510c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // actually added to the conference or not. false implies that it either 511c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // is not part of a merging conference or already knows if it was 512c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // successfully added. 513047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn private boolean mCallSessionMergePending = false; 514047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn 515ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 51695d563ed2a215d67a4f789c3ebb5a526fb95cc7fTyler Gunn * If {@code true}, this flag indicates that a request to terminate the call was made by 51795d563ed2a215d67a4f789c3ebb5a526fb95cc7fTyler Gunn * Telephony (could be from the user or some internal telephony logic) 51895d563ed2a215d67a4f789c3ebb5a526fb95cc7fTyler Gunn * and that when we receive a {@link #processCallTerminated(ImsReasonInfo)} callback from the 51995d563ed2a215d67a4f789c3ebb5a526fb95cc7fTyler Gunn * radio indicating that the call was terminated, we should override any burying of the 52095d563ed2a215d67a4f789c3ebb5a526fb95cc7fTyler Gunn * termination due to an ongoing conference merge. 52195d563ed2a215d67a4f789c3ebb5a526fb95cc7fTyler Gunn */ 52295d563ed2a215d67a4f789c3ebb5a526fb95cc7fTyler Gunn private boolean mTerminationRequestPending = false; 52395d563ed2a215d67a4f789c3ebb5a526fb95cc7fTyler Gunn 52495d563ed2a215d67a4f789c3ebb5a526fb95cc7fTyler Gunn /** 52525394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * For multi-party IMS calls (e.g. conferences), determines if this {@link ImsCall} is the one 52625394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * hosting the call. This is used to distinguish between a situation where an {@link ImsCall} 52725394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * is {@link #isMultiparty()} because calls were merged on the device, and a situation where 52825394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * an {@link ImsCall} is {@link #isMultiparty()} because it is a member of a conference started 52925394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * on another device. 53025394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * <p> 53125394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * When {@code true}, this {@link ImsCall} is is the origin of the conference call. 53225394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * When {@code false}, this {@link ImsCall} is a member of a conference started on another 53325394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * device. 53425394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn */ 53525394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn private boolean mIsConferenceHost = false; 53625394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn 53725394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn /** 538ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Create an IMS call object. 539ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 540ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param context the context for accessing system services 541ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param profile the call profile to make/take a call 542ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 543ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public ImsCall(Context context, ImsCallProfile profile) { 544ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mContext = context; 545ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mCallProfile = profile; 546ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 547ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 548ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 549ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Closes this object. This object is not usable after being closed. 550ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 551ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 552ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void close() { 553ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 554ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mSession != null) { 555ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mSession.close(); 556ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mSession = null; 55795be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam } else { 55895be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam logi("close :: Cannot close Null call session!"); 559ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 560ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 561ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mCallProfile = null; 562ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mProposedCallProfile = null; 563ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mLastReasonInfo = null; 564ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mMediaSession = null; 565ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 566ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 567ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 568ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 569ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Checks if the call has a same remote user identity or not. 570ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 571ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param userId the remote user identity 572ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @return true if the remote user identity is equal; otherwise, false 573ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 574ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 575ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public boolean checkIfRemoteUserIsSame(String userId) { 576ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (userId == null) { 577ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return false; 578ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 579ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 580ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return userId.equals(mCallProfile.getCallExtra(ImsCallProfile.EXTRA_REMOTE_URI, "")); 581ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 582ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 583ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 584ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Checks if the call is equal or not. 585ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 586ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param call the call to be compared 587ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @return true if the call is equal; otherwise, false 588ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 589ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 590ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public boolean equalsTo(ICall call) { 591ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (call == null) { 592ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return false; 593ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 594ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 595ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (call instanceof ImsCall) { 59616b3b36eb554d27f23b05577c6a76a9b989bdbcdEtan Cohen return this.equals(call); 597ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 598ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 599ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return false; 600ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 601ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 602c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee public static boolean isSessionAlive(ImsCallSession session) { 603c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee return session != null && session.isAlive(); 604c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } 605c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee 606ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 607ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Gets the negotiated (local & remote) call profile. 608ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 609ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @return a {@link ImsCallProfile} object that has the negotiated call profile 610ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 611ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public ImsCallProfile getCallProfile() { 612ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 613ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return mCallProfile; 614ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 615ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 616ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 617ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 618ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Gets the local call profile (local capabilities). 619ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 620ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @return a {@link ImsCallProfile} object that has the local call profile 621ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 622ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public ImsCallProfile getLocalCallProfile() throws ImsException { 623ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 624ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mSession == null) { 625ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("No call session", 626ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED); 627ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 628ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 629ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 630ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return mSession.getLocalCallProfile(); 631ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 632ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("getLocalCallProfile :: ", t); 633ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("getLocalCallProfile()", t, 0); 634ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 635ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 636ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 637ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 638ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 639e871989b4d1c6590e7c280cbdd90c75ca82a877eShriram Ganesh * Gets the remote call profile (remote capabilities). 640e871989b4d1c6590e7c280cbdd90c75ca82a877eShriram Ganesh * 641e871989b4d1c6590e7c280cbdd90c75ca82a877eShriram Ganesh * @return a {@link ImsCallProfile} object that has the remote call profile 642e871989b4d1c6590e7c280cbdd90c75ca82a877eShriram Ganesh */ 643e871989b4d1c6590e7c280cbdd90c75ca82a877eShriram Ganesh public ImsCallProfile getRemoteCallProfile() throws ImsException { 644e871989b4d1c6590e7c280cbdd90c75ca82a877eShriram Ganesh synchronized(mLockObj) { 645e871989b4d1c6590e7c280cbdd90c75ca82a877eShriram Ganesh if (mSession == null) { 646e871989b4d1c6590e7c280cbdd90c75ca82a877eShriram Ganesh throw new ImsException("No call session", 647e871989b4d1c6590e7c280cbdd90c75ca82a877eShriram Ganesh ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED); 648e871989b4d1c6590e7c280cbdd90c75ca82a877eShriram Ganesh } 649e871989b4d1c6590e7c280cbdd90c75ca82a877eShriram Ganesh 650e871989b4d1c6590e7c280cbdd90c75ca82a877eShriram Ganesh try { 651e871989b4d1c6590e7c280cbdd90c75ca82a877eShriram Ganesh return mSession.getRemoteCallProfile(); 652e871989b4d1c6590e7c280cbdd90c75ca82a877eShriram Ganesh } catch (Throwable t) { 653e871989b4d1c6590e7c280cbdd90c75ca82a877eShriram Ganesh loge("getRemoteCallProfile :: ", t); 654e871989b4d1c6590e7c280cbdd90c75ca82a877eShriram Ganesh throw new ImsException("getRemoteCallProfile()", t, 0); 655e871989b4d1c6590e7c280cbdd90c75ca82a877eShriram Ganesh } 656e871989b4d1c6590e7c280cbdd90c75ca82a877eShriram Ganesh } 657e871989b4d1c6590e7c280cbdd90c75ca82a877eShriram Ganesh } 658e871989b4d1c6590e7c280cbdd90c75ca82a877eShriram Ganesh 659e871989b4d1c6590e7c280cbdd90c75ca82a877eShriram Ganesh /** 660ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Gets the call profile proposed by the local/remote user. 661ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 662ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @return a {@link ImsCallProfile} object that has the proposed call profile 663ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 664ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public ImsCallProfile getProposedCallProfile() { 665ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 666ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (!isInCall()) { 667ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return null; 668ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 669ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 670ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return mProposedCallProfile; 671ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 672ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 673ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 674ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 675a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam * Gets the list of conference participants currently 676a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam * associated with this call. 677a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam * 678a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam * @return The list of conference participants. 679a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam */ 680a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam public List<ConferenceParticipant> getConferenceParticipants() { 681a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam synchronized(mLockObj) { 682a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam logi("getConferenceParticipants :: mConferenceParticipants" 683a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam + mConferenceParticipants); 684a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam return mConferenceParticipants; 685a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam } 686a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam } 687a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam 688a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam /** 689ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Gets the state of the {@link ImsCallSession} that carries this call. 690ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * The value returned must be one of the states in {@link ImsCallSession#State}. 691ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 692ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @return the session state 693ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 694ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public int getState() { 695ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 696ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mSession == null) { 697ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return ImsCallSession.State.IDLE; 698ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 699ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 700ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return mSession.getState(); 701ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 702ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 703ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 704ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 705ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Gets the {@link ImsCallSession} that carries this call. 706ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 707ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @return the session object that carries this call 708ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @hide 709ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 710ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public ImsCallSession getCallSession() { 711ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 712ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return mSession; 713ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 714ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 715ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 716ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 717ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Gets the {@link ImsStreamMediaSession} that handles the media operation of this call. 718ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Almost interface APIs are for the VT (Video Telephony). 719ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 720ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @return the media session object that handles the media operation of this call 721ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @hide 722ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 723ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public ImsStreamMediaSession getMediaSession() { 724ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 725ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return mMediaSession; 726ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 727ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 728ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 729ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 730ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Gets the specified property of this call. 731ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 732ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param name key to get the extra call information defined in {@link ImsCallProfile} 733ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @return the extra call information as string 734ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 735ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public String getCallExtra(String name) throws ImsException { 736ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // Lookup the cache 737ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 738ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 739ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // If not found, try to get the property from the remote 740ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mSession == null) { 741ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("No call session", 742ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED); 743ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 744ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 745ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 746ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return mSession.getProperty(name); 747ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 748ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("getCallExtra :: ", t); 749ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("getCallExtra()", t, 0); 750ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 751ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 752ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 753ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 754ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 755ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Gets the last reason information when the call is not established, cancelled or terminated. 756ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 757ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @return the last reason information 758ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 759ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public ImsReasonInfo getLastReasonInfo() { 760ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 761ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return mLastReasonInfo; 762ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 763ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 764ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 765ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 766ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Checks if the call has a pending update operation. 767ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 768ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @return true if the call has a pending update operation 769ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 770ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public boolean hasPendingUpdate() { 771ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 772ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return (mUpdateRequest != UPDATE_NONE); 773ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 774ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 775ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 776ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 7776c0b0d0e83b8d06f40ec814573adc69f362704a9Tyler Gunn * Checks if the call is pending a hold operation. 7786c0b0d0e83b8d06f40ec814573adc69f362704a9Tyler Gunn * 7796c0b0d0e83b8d06f40ec814573adc69f362704a9Tyler Gunn * @return true if the call is pending a hold operation. 7806c0b0d0e83b8d06f40ec814573adc69f362704a9Tyler Gunn */ 7816c0b0d0e83b8d06f40ec814573adc69f362704a9Tyler Gunn public boolean isPendingHold() { 7826c0b0d0e83b8d06f40ec814573adc69f362704a9Tyler Gunn synchronized(mLockObj) { 7836c0b0d0e83b8d06f40ec814573adc69f362704a9Tyler Gunn return (mUpdateRequest == UPDATE_HOLD); 7846c0b0d0e83b8d06f40ec814573adc69f362704a9Tyler Gunn } 7856c0b0d0e83b8d06f40ec814573adc69f362704a9Tyler Gunn } 7866c0b0d0e83b8d06f40ec814573adc69f362704a9Tyler Gunn 7876c0b0d0e83b8d06f40ec814573adc69f362704a9Tyler Gunn /** 788ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Checks if the call is established. 789ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 790ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @return true if the call is established 791ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 792ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public boolean isInCall() { 793ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 794ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return mInCall; 795ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 796ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 797ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 798ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 799ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Checks if the call is muted. 800ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 801ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @return true if the call is muted 802ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 803ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public boolean isMuted() { 804ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 805ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return mMute; 806ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 807ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 808ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 809ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 810ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Checks if the call is on hold. 811ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 812ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @return true if the call is on hold 813ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 814ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public boolean isOnHold() { 815ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 816ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return mHold; 817ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 818ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 819ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 820ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 821725ad373383798c1516348475b1f6304484e031eTyler Gunn * Determines if the call is a multiparty call. 822725ad373383798c1516348475b1f6304484e031eTyler Gunn * 823725ad373383798c1516348475b1f6304484e031eTyler Gunn * @return {@code True} if the call is a multiparty call. 824725ad373383798c1516348475b1f6304484e031eTyler Gunn */ 825725ad373383798c1516348475b1f6304484e031eTyler Gunn public boolean isMultiparty() { 82616b3b36eb554d27f23b05577c6a76a9b989bdbcdEtan Cohen synchronized(mLockObj) { 82716b3b36eb554d27f23b05577c6a76a9b989bdbcdEtan Cohen if (mSession == null) { 82816b3b36eb554d27f23b05577c6a76a9b989bdbcdEtan Cohen return false; 82916b3b36eb554d27f23b05577c6a76a9b989bdbcdEtan Cohen } 83016b3b36eb554d27f23b05577c6a76a9b989bdbcdEtan Cohen 83171382693cbc81b1d131085f52d97879976706f55Anthony Lee return mSession.isMultiparty(); 83216b3b36eb554d27f23b05577c6a76a9b989bdbcdEtan Cohen } 833725ad373383798c1516348475b1f6304484e031eTyler Gunn } 834725ad373383798c1516348475b1f6304484e031eTyler Gunn 835725ad373383798c1516348475b1f6304484e031eTyler Gunn /** 83625394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * Where {@link #isMultiparty()} is {@code true}, determines if this {@link ImsCall} is the 83725394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * origin of the conference call (i.e. {@code #isConferenceHost()} is {@code true}), or if this 83825394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * {@link ImsCall} is a member of a conference hosted on another device. 83925394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * 84025394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * @return {@code true} if this call is the origin of the conference call it is a member of, 84125394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * {@code false} otherwise. 84225394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn */ 84325394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn public boolean isConferenceHost() { 84425394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn synchronized(mLockObj) { 84525394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn return isMultiparty() && mIsConferenceHost; 84625394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn } 84725394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn } 84825394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn 84925394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn /** 8509bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * Marks whether an IMS call is merged. This should be set {@code true} when the call merges 8519bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * into a conference. 8528ae59492156d9cef275f559c5ee09a44315989beAndrew Lee * 8538ae59492156d9cef275f559c5ee09a44315989beAndrew Lee * @param isMerged Whether the call is merged. 8548ae59492156d9cef275f559c5ee09a44315989beAndrew Lee */ 8558ae59492156d9cef275f559c5ee09a44315989beAndrew Lee public void setIsMerged(boolean isMerged) { 8568ae59492156d9cef275f559c5ee09a44315989beAndrew Lee mIsMerged = isMerged; 8578ae59492156d9cef275f559c5ee09a44315989beAndrew Lee } 8588ae59492156d9cef275f559c5ee09a44315989beAndrew Lee 8598ae59492156d9cef275f559c5ee09a44315989beAndrew Lee /** 8609bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * @return {@code true} if the call recently merged into a conference call. 8618ae59492156d9cef275f559c5ee09a44315989beAndrew Lee */ 8628ae59492156d9cef275f559c5ee09a44315989beAndrew Lee public boolean isMerged() { 8638ae59492156d9cef275f559c5ee09a44315989beAndrew Lee return mIsMerged; 8648ae59492156d9cef275f559c5ee09a44315989beAndrew Lee } 8658ae59492156d9cef275f559c5ee09a44315989beAndrew Lee 8668ae59492156d9cef275f559c5ee09a44315989beAndrew Lee /** 867ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Sets the listener to listen to the IMS call events. 868ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * The method calls {@link #setListener setListener(listener, false)}. 869ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 870ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param listener to listen to the IMS call events of this object; null to remove listener 871ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @see #setListener(Listener, boolean) 872ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 873ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void setListener(ImsCall.Listener listener) { 874ef36ef67e009449300b0150c60c9f637e205d79eWink Saville setListener(listener, false); 875ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 876ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 877ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 878ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Sets the listener to listen to the IMS call events. 879ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * A {@link ImsCall} can only hold one listener at a time. Subsequent calls 880ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * to this method override the previous listener. 881ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 882ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param listener to listen to the IMS call events of this object; null to remove listener 883ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param callbackImmediately set to true if the caller wants to be called 884ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * back immediately on the current state 885ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 886ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void setListener(ImsCall.Listener listener, boolean callbackImmediately) { 887ef36ef67e009449300b0150c60c9f637e205d79eWink Saville boolean inCall; 888ef36ef67e009449300b0150c60c9f637e205d79eWink Saville boolean onHold; 889ef36ef67e009449300b0150c60c9f637e205d79eWink Saville int state; 890ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo lastReasonInfo; 891ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 892ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 893ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mListener = listener; 894ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 895ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if ((listener == null) || !callbackImmediately) { 896ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return; 897ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 898ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 899ef36ef67e009449300b0150c60c9f637e205d79eWink Saville inCall = mInCall; 900ef36ef67e009449300b0150c60c9f637e205d79eWink Saville onHold = mHold; 901ef36ef67e009449300b0150c60c9f637e205d79eWink Saville state = getState(); 902ef36ef67e009449300b0150c60c9f637e205d79eWink Saville lastReasonInfo = mLastReasonInfo; 903ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 904ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 905ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 906ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (lastReasonInfo != null) { 907ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallError(this, lastReasonInfo); 908ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } else if (inCall) { 909ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (onHold) { 910ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallHeld(this); 911ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } else { 912ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallStarted(this); 913ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 914ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } else { 915ef36ef67e009449300b0150c60c9f637e205d79eWink Saville switch (state) { 916ef36ef67e009449300b0150c60c9f637e205d79eWink Saville case ImsCallSession.State.ESTABLISHING: 917ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallProgressing(this); 918ef36ef67e009449300b0150c60c9f637e205d79eWink Saville break; 919ef36ef67e009449300b0150c60c9f637e205d79eWink Saville case ImsCallSession.State.TERMINATED: 920ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallTerminated(this, lastReasonInfo); 921ef36ef67e009449300b0150c60c9f637e205d79eWink Saville break; 922ef36ef67e009449300b0150c60c9f637e205d79eWink Saville default: 923ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // Ignore it. There is no action in the other state. 924ef36ef67e009449300b0150c60c9f637e205d79eWink Saville break; 925ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 926ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 927ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 9286804851b58264d7e82b09a845118d24d36c8d831Anthony Lee loge("setListener() :: ", t); 929ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 930ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 931ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 932ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 933ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Mutes or unmutes the mic for the active call. 934ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 935ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param muted true if the call is muted, false otherwise 936ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 937ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void setMute(boolean muted) throws ImsException { 938ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 939ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mMute != muted) { 9406804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("setMute :: turning mute " + (muted ? "on" : "off")); 941ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mMute = muted; 942ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 943ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 944ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mSession.setMute(muted); 945ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 946ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("setMute :: ", t); 947ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throwImsException(t, 0); 948ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 949ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 950ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 951ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 952ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 953ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 954ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Attaches an incoming call to this call object. 955ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 956ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param session the session that receives the incoming call 957ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @throws ImsException if the IMS service fails to attach this object to the session 958ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 959ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void attachSession(ImsCallSession session) throws ImsException { 9606804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("attachSession :: session=" + session); 961ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 962ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 963ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mSession = session; 964ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 965ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 966ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mSession.setListener(createCallSessionListener()); 967ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 968ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("attachSession :: ", t); 969ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throwImsException(t, 0); 970ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 971ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 972ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 973ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 974ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 975ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Initiates an IMS call with the call profile which is provided 976ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * when creating a {@link ImsCall}. 977ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 978ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param session the {@link ImsCallSession} for carrying out the call 979ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param callee callee information to initiate an IMS call 980ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @throws ImsException if the IMS service fails to initiate the call 981ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 982ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void start(ImsCallSession session, String callee) 983ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throws ImsException { 9846804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("start(1) :: session=" + session + ", callee=" + callee); 985ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 986ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 987ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mSession = session; 988ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 989ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 990ef36ef67e009449300b0150c60c9f637e205d79eWink Saville session.setListener(createCallSessionListener()); 991ef36ef67e009449300b0150c60c9f637e205d79eWink Saville session.start(callee, mCallProfile); 992ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 993ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("start(1) :: ", t); 994ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("start(1)", t, 0); 995ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 996ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 997ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 998ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 999ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 1000ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Initiates an IMS conferenca call with the call profile which is provided 1001ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * when creating a {@link ImsCall}. 1002ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 1003ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param session the {@link ImsCallSession} for carrying out the call 1004ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param participants participant list to initiate an IMS conference call 1005ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @throws ImsException if the IMS service fails to initiate the call 1006ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 1007ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void start(ImsCallSession session, String[] participants) 1008ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throws ImsException { 10096804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("start(n) :: session=" + session + ", callee=" + participants); 1010ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1011ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 1012ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mSession = session; 1013ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1014ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 1015ef36ef67e009449300b0150c60c9f637e205d79eWink Saville session.setListener(createCallSessionListener()); 1016ef36ef67e009449300b0150c60c9f637e205d79eWink Saville session.start(participants, mCallProfile); 1017ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 1018ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("start(n) :: ", t); 1019ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("start(n)", t, 0); 1020ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1021ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1022ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1023ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1024ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 1025ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Accepts a call. 1026ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 1027ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @see Listener#onCallStarted 1028d1edfd8cf9ffeb191a84e08522bb570cd8cd4381Tyler Gunn * 1029d1edfd8cf9ffeb191a84e08522bb570cd8cd4381Tyler Gunn * @param callType The call type the user agreed to for accepting the call. 1030ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @throws ImsException if the IMS service fails to accept the call 1031ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 1032d1edfd8cf9ffeb191a84e08522bb570cd8cd4381Tyler Gunn public void accept(int callType) throws ImsException { 1033d1edfd8cf9ffeb191a84e08522bb570cd8cd4381Tyler Gunn accept(callType, new ImsStreamMediaProfile()); 1034ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1035ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1036ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 1037ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Accepts a call. 1038ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 1039ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param callType call type to be answered in {@link ImsCallProfile} 1040ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param profile a media profile to be answered (audio/audio & video, direction, ...) 1041ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @see Listener#onCallStarted 1042ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @throws ImsException if the IMS service fails to accept the call 1043ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 1044ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void accept(int callType, ImsStreamMediaProfile profile) throws ImsException { 10456804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("accept :: callType=" + callType + ", profile=" + profile); 1046ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1047ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 1048ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mSession == null) { 1049ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("No call to answer", 1050ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED); 1051ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1052ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1053ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 1054ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mSession.accept(callType, profile); 1055ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 1056ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("accept :: ", t); 1057ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("accept()", t, 0); 1058ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1059ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1060ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mInCall && (mProposedCallProfile != null)) { 1061ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (DBG) { 10626804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("accept :: call profile will be updated"); 1063ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1064ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1065ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mCallProfile = mProposedCallProfile; 1066ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mProposedCallProfile = null; 1067ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1068ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1069ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // Other call update received 1070ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mInCall && (mUpdateRequest == UPDATE_UNSPECIFIED)) { 1071ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mUpdateRequest = UPDATE_NONE; 1072ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1073ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1074ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1075ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1076ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 1077ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Rejects a call. 1078ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 1079ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param reason reason code to reject an incoming call 1080ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @see Listener#onCallStartFailed 10816804851b58264d7e82b09a845118d24d36c8d831Anthony Lee * @throws ImsException if the IMS service fails to reject the call 1082ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 1083ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void reject(int reason) throws ImsException { 10846804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("reject :: reason=" + reason); 1085ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1086ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 1087ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mSession != null) { 1088ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mSession.reject(reason); 1089ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1090ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1091ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mInCall && (mProposedCallProfile != null)) { 1092ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (DBG) { 10936804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("reject :: call profile is not updated; destroy it..."); 1094ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1095ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1096ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mProposedCallProfile = null; 1097ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1098ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1099ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // Other call update received 1100ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mInCall && (mUpdateRequest == UPDATE_UNSPECIFIED)) { 1101ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mUpdateRequest = UPDATE_NONE; 1102ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1103ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1104ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1105ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1106ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 110795d563ed2a215d67a4f789c3ebb5a526fb95cc7fTyler Gunn * Terminates an IMS call (e.g. user initiated). 1108ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 1109ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param reason reason code to terminate a call 1110ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @throws ImsException if the IMS service fails to terminate the call 1111ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 1112ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void terminate(int reason) throws ImsException { 11136804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("terminate :: reason=" + reason); 1114ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1115ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 1116ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mHold = false; 1117ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mInCall = false; 111895d563ed2a215d67a4f789c3ebb5a526fb95cc7fTyler Gunn mTerminationRequestPending = true; 1119ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1120ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mSession != null) { 1121c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // TODO: Fix the fact that user invoked call terminations during 1122c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // the process of establishing a conference call needs to be handled 1123c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // as a special case. 1124c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // Currently, any terminations (both invoked by the user or 1125c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // by the network results in a callSessionTerminated() callback 1126c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // from the network. When establishing a conference call we bury 1127c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // these callbacks until we get closure on all participants of the 1128c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // conference. In some situations, we will throw away the callback 1129c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // (when the underlying session of the host of the new conference 1130c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // is terminated) or will will unbury it when the conference has been 1131c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // established, like when the peer of the new conference goes away 1132c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // after the conference has been created. The UI relies on the callback 1133c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // to reflect the fact that the call is gone. 1134c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // So if a user decides to terminated a call while it is merging, it 1135c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // could take a long time to reflect in the UI due to the conference 1136c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // processing but we should probably cancel that and just terminate 1137c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // the call immediately and clean up. This is not a huge issue right 1138c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // now because we have not seen instances where establishing a 1139c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // conference takes a long time (more than a second or two). 1140ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mSession.terminate(reason); 1141ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1142ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1143ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1144ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1145d43b5302d8edf4df90a28055f043786f542df219Uma Maheswari Ramalingam 1146ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 1147ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Puts a call on hold. When succeeds, {@link Listener#onCallHeld} is called. 1148ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 1149ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @see Listener#onCallHeld, Listener#onCallHoldFailed 1150ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @throws ImsException if the IMS service fails to hold the call 1151ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 1152ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void hold() throws ImsException { 11536804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("hold :: "); 1154111eecc9845826e985c48133b754e453fb3aca84Etan Cohen 1155ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (isOnHold()) { 1156ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (DBG) { 11576804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("hold :: call is already on hold"); 1158ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1159ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return; 1160ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1161ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1162ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 1163ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mUpdateRequest != UPDATE_NONE) { 11649bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn loge("hold :: update is in progress; request=" + 11659bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn updateRequestToString(mUpdateRequest)); 1166ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("Call update is in progress", 1167ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo.CODE_LOCAL_ILLEGAL_STATE); 1168ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1169ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1170ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mSession == null) { 1171ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("No call session", 1172ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED); 1173ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1174ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1175ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mSession.hold(createHoldMediaProfile()); 11766804851b58264d7e82b09a845118d24d36c8d831Anthony Lee // FIXME: We should update the state on the callback because that is where 11776804851b58264d7e82b09a845118d24d36c8d831Anthony Lee // we can confirm that the hold request was successful or not. 1178ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mHold = true; 1179ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mUpdateRequest = UPDATE_HOLD; 1180ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1181ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1182ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1183ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 1184ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Continues a call that's on hold. When succeeds, {@link Listener#onCallResumed} is called. 1185ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 1186ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @see Listener#onCallResumed, Listener#onCallResumeFailed 1187ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @throws ImsException if the IMS service fails to resume the call 1188ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 1189ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void resume() throws ImsException { 11906804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("resume :: "); 1191111eecc9845826e985c48133b754e453fb3aca84Etan Cohen 1192ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (!isOnHold()) { 1193ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (DBG) { 11946804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("resume :: call is not being held"); 1195ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1196ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return; 1197ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1198ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1199ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 1200ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mUpdateRequest != UPDATE_NONE) { 12019bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn loge("resume :: update is in progress; request=" + 12029bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn updateRequestToString(mUpdateRequest)); 1203ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("Call update is in progress", 1204ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo.CODE_LOCAL_ILLEGAL_STATE); 1205ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1206ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1207ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mSession == null) { 1208ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("resume :: "); 1209ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("No call session", 1210ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED); 1211ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1212ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1213c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // mHold is set to false in confirmation callback that the 1214c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // ImsCall was resumed. 1215ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mUpdateRequest = UPDATE_RESUME; 1216c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee mSession.resume(createResumeMediaProfile()); 1217ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1218ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1219ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1220ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 1221ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Merges the active & hold call. 1222ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 1223ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @see Listener#onCallMerged, Listener#onCallMergeFailed 1224ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @throws ImsException if the IMS service fails to merge the call 1225ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 1226047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn private void merge() throws ImsException { 12276804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("merge :: "); 1228ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1229ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 1230ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mUpdateRequest != UPDATE_NONE) { 12319bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn loge("merge :: update is in progress; request=" + 12329bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn updateRequestToString(mUpdateRequest)); 1233ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("Call update is in progress", 1234ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo.CODE_LOCAL_ILLEGAL_STATE); 1235ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1236ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1237ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mSession == null) { 1238c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee loge("merge :: no call session"); 1239ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("No call session", 1240ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED); 1241ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1242ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1243ca45f58a57eb782153c034ae067f59c0018799caUma Maheswari Ramalingam // if skipHoldBeforeMerge = true, IMS service implementation will 1244ca45f58a57eb782153c034ae067f59c0018799caUma Maheswari Ramalingam // merge without explicitly holding the call. 1245ca45f58a57eb782153c034ae067f59c0018799caUma Maheswari Ramalingam if (mHold || (mContext.getResources().getBoolean( 1246ca45f58a57eb782153c034ae067f59c0018799caUma Maheswari Ramalingam com.android.internal.R.bool.skipHoldBeforeMerge))) { 1247b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee 12489bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn if (mMergePeer != null && !mMergePeer.isMultiparty() && !isMultiparty()) { 12499bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn // We only set UPDATE_MERGE when we are adding the first 12509bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn // calls to the Conference. If there is already a conference 1251047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn // no special handling is needed. The existing conference 12529bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn // session will just go active and any other sessions will be terminated 12539bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn // if needed. There will be no merge failed callback. 1254047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn // Mark both the host and peer UPDATE_MERGE to ensure both are aware that a 1255047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn // merge is pending. 12569bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn mUpdateRequest = UPDATE_MERGE; 1257047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn mMergePeer.mUpdateRequest = UPDATE_MERGE; 1258b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee } 12599bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn 12609bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn mSession.merge(); 1261ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } else { 126271382693cbc81b1d131085f52d97879976706f55Anthony Lee // This code basically says, we need to explicitly hold before requesting a merge 126371382693cbc81b1d131085f52d97879976706f55Anthony Lee // when we get the callback that the hold was successful (or failed), we should 126471382693cbc81b1d131085f52d97879976706f55Anthony Lee // automatically request a merge. 1265ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mSession.hold(createHoldMediaProfile()); 1266ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mHold = true; 1267ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mUpdateRequest = UPDATE_HOLD_MERGE; 1268ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1269ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1270ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1271ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1272ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 1273ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Merges the active & hold call. 1274ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 1275ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param bgCall the background (holding) call 1276ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @see Listener#onCallMerged, Listener#onCallMergeFailed 1277ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @throws ImsException if the IMS service fails to merge the call 1278ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 1279ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void merge(ImsCall bgCall) throws ImsException { 12806804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("merge(1) :: bgImsCall=" + bgCall); 1281ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1282ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (bgCall == null) { 1283ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("No background call", 1284ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT); 1285ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1286ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1287ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 1288047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn // Mark both sessions as pending merge. 1289047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn this.setCallSessionMergePending(true); 1290047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn bgCall.setCallSessionMergePending(true); 1291047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn 129287466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn if ((!isMultiparty() && !bgCall.isMultiparty()) || isMultiparty()) { 129387466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn // If neither call is multiparty, the current call is the merge host and the bg call 129487466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn // is the merge peer (ie we're starting a new conference). 129587466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn // OR 129687466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn // If this call is multiparty, it is the merge host and the other call is the merge 129787466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn // peer. 129887466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn setMergePeer(bgCall); 129987466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn } else { 130087466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn // If the bg call is multiparty, it is the merge host. 130187466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn setMergeHost(bgCall); 130287466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn } 1303ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1304a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam 130595be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam if (isMultiparty()) { 130695be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam mMergeRequestedByConference = true; 130795be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam } else { 130895be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam logi("merge : mMergeRequestedByConference not set"); 130995be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam } 1310ef36ef67e009449300b0150c60c9f637e205d79eWink Saville merge(); 1311ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1312ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1313ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 1314ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Updates the current call's properties (ex. call mode change: video upgrade / downgrade). 1315ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 1316ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void update(int callType, ImsStreamMediaProfile mediaProfile) throws ImsException { 13176804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("update :: callType=" + callType + ", mediaProfile=" + mediaProfile); 1318ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1319ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (isOnHold()) { 1320ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (DBG) { 13216804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("update :: call is on hold"); 1322ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1323ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("Not in a call to update call", 1324ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo.CODE_LOCAL_ILLEGAL_STATE); 1325ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1326ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1327ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 1328ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mUpdateRequest != UPDATE_NONE) { 1329ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (DBG) { 13306804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("update :: update is in progress; request=" + 13319bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn updateRequestToString(mUpdateRequest)); 1332ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1333ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("Call update is in progress", 1334ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo.CODE_LOCAL_ILLEGAL_STATE); 1335ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1336ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1337ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mSession == null) { 1338ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("update :: "); 1339ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("No call session", 1340ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED); 1341ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1342ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1343ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mSession.update(callType, mediaProfile); 1344ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mUpdateRequest = UPDATE_UNSPECIFIED; 1345ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1346ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1347ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1348ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 1349ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Extends this call (1-to-1 call) to the conference call 1350ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * inviting the specified participants to. 1351ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 1352ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 1353ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void extendToConference(String[] participants) throws ImsException { 13546804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("extendToConference ::"); 1355ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1356ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (isOnHold()) { 1357ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (DBG) { 13586804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("extendToConference :: call is on hold"); 1359ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1360ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("Not in a call to extend a call to conference", 1361ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo.CODE_LOCAL_ILLEGAL_STATE); 1362ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1363ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1364ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 1365ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mUpdateRequest != UPDATE_NONE) { 13666804851b58264d7e82b09a845118d24d36c8d831Anthony Lee if (CONF_DBG) { 13676804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("extendToConference :: update is in progress; request=" + 13689bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn updateRequestToString(mUpdateRequest)); 1369ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1370ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("Call update is in progress", 1371ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo.CODE_LOCAL_ILLEGAL_STATE); 1372ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1373ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1374ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mSession == null) { 1375ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("extendToConference :: "); 1376ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("No call session", 1377ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED); 1378ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1379ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1380ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mSession.extendToConference(participants); 1381ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mUpdateRequest = UPDATE_EXTEND_TO_CONFERENCE; 1382ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1383ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1384ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1385ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 1386ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Requests the conference server to invite an additional participants to the conference. 1387ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 1388ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 1389ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void inviteParticipants(String[] participants) throws ImsException { 13906804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("inviteParticipants ::"); 1391ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1392ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 1393ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mSession == null) { 1394ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("inviteParticipants :: "); 1395ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("No call session", 1396ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED); 1397ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1398ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1399ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mSession.inviteParticipants(participants); 1400ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1401ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1402ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1403ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 1404ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Requests the conference server to remove the specified participants from the conference. 1405ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 1406ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 1407ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void removeParticipants(String[] participants) throws ImsException { 1408a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam logi("removeParticipants :: session=" + mSession); 1409ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 1410ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mSession == null) { 1411ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("removeParticipants :: "); 1412ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("No call session", 1413ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED); 1414ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1415ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1416ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mSession.removeParticipants(participants); 1417a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam 1418ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1419ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1420ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1421ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 1422ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Sends a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833</a>, 1423ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15, 1424ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * and event flash to 16. Currently, event flash is not supported. 1425ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 14262f92daf76a66d7d2fe6fb7b1a28fc1b5888a7b7cLibin.Tang@motorola.com * @param c that represents the DTMF to send. '0' ~ '9', 'A' ~ 'D', '*', '#' are valid inputs. 14272f92daf76a66d7d2fe6fb7b1a28fc1b5888a7b7cLibin.Tang@motorola.com * @param result the result message to send when done. 1428ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 14292f92daf76a66d7d2fe6fb7b1a28fc1b5888a7b7cLibin.Tang@motorola.com public void sendDtmf(char c, Message result) { 14306804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("sendDtmf :: code=" + c); 1431ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1432ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 1433ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mSession != null) { 1434a4710d5d926d8112179acece620f49cb79257e98Andrew Lee mSession.sendDtmf(c, result); 1435ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1436ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1437ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1438ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1439ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 1440a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam * Start a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833</a>, 1441a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15, 1442a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam * and event flash to 16. Currently, event flash is not supported. 1443a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam * 1444a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam * @param c that represents the DTMF to send. '0' ~ '9', 'A' ~ 'D', '*', '#' are valid inputs. 1445a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam */ 1446a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam public void startDtmf(char c) { 14476804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("startDtmf :: code=" + c); 1448a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam 1449a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam synchronized(mLockObj) { 1450a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam if (mSession != null) { 1451a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam mSession.startDtmf(c); 1452a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam } 1453a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam } 1454a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam } 1455a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam 1456a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam /** 1457a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam * Stop a DTMF code. 1458a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam */ 1459a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam public void stopDtmf() { 14606804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("stopDtmf :: "); 1461a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam 1462a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam synchronized(mLockObj) { 1463a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam if (mSession != null) { 1464a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam mSession.stopDtmf(); 1465a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam } 1466a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam } 1467a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam } 1468a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam 1469a6fbae9f8c793118e008a98d3576df316bf0364aUma Maheswari Ramalingam /** 1470ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Sends an USSD message. 1471ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * 1472ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * @param ussdMessage USSD message to send 1473ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 1474ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void sendUssd(String ussdMessage) throws ImsException { 14756804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("sendUssd :: ussdMessage=" + ussdMessage); 1476ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1477ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(mLockObj) { 1478ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mSession == null) { 1479ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("sendUssd :: "); 1480ef36ef67e009449300b0150c60c9f637e205d79eWink Saville throw new ImsException("No call session", 1481ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED); 1482ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1483ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1484ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mSession.sendUssd(ussdMessage); 1485ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1486ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1487ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1488ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private void clear(ImsReasonInfo lastReasonInfo) { 1489ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mInCall = false; 1490ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mHold = false; 1491ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mUpdateRequest = UPDATE_NONE; 1492ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mLastReasonInfo = lastReasonInfo; 1493ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1494ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1495ef36ef67e009449300b0150c60c9f637e205d79eWink Saville /** 1496ef36ef67e009449300b0150c60c9f637e205d79eWink Saville * Creates an IMS call session listener. 1497ef36ef67e009449300b0150c60c9f637e205d79eWink Saville */ 1498ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private ImsCallSession.Listener createCallSessionListener() { 1499ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return new ImsCallSessionListenerProxy(); 1500ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1501ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1502ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private ImsCall createNewCall(ImsCallSession session, ImsCallProfile profile) { 1503ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall call = new ImsCall(mContext, profile); 1504ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1505ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 1506ef36ef67e009449300b0150c60c9f637e205d79eWink Saville call.attachSession(session); 1507ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (ImsException e) { 1508ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (call != null) { 1509ef36ef67e009449300b0150c60c9f637e205d79eWink Saville call.close(); 1510ef36ef67e009449300b0150c60c9f637e205d79eWink Saville call = null; 1511ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1512ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1513ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1514ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // Do additional operations... 1515ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1516ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return call; 1517ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1518ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1519ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private ImsStreamMediaProfile createHoldMediaProfile() { 1520ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsStreamMediaProfile mediaProfile = new ImsStreamMediaProfile(); 1521ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1522ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mCallProfile == null) { 1523ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return mediaProfile; 1524ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1525ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1526ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mediaProfile.mAudioQuality = mCallProfile.mMediaProfile.mAudioQuality; 1527ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mediaProfile.mVideoQuality = mCallProfile.mMediaProfile.mVideoQuality; 1528ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mediaProfile.mAudioDirection = ImsStreamMediaProfile.DIRECTION_SEND; 1529ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1530ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mediaProfile.mVideoQuality != ImsStreamMediaProfile.VIDEO_QUALITY_NONE) { 1531ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mediaProfile.mVideoDirection = ImsStreamMediaProfile.DIRECTION_SEND; 1532ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1533ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1534ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return mediaProfile; 1535ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1536ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1537ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private ImsStreamMediaProfile createResumeMediaProfile() { 1538ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsStreamMediaProfile mediaProfile = new ImsStreamMediaProfile(); 1539ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1540ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mCallProfile == null) { 1541ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return mediaProfile; 1542ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1543ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1544ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mediaProfile.mAudioQuality = mCallProfile.mMediaProfile.mAudioQuality; 1545ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mediaProfile.mVideoQuality = mCallProfile.mMediaProfile.mVideoQuality; 1546ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mediaProfile.mAudioDirection = ImsStreamMediaProfile.DIRECTION_SEND_RECEIVE; 1547ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1548ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mediaProfile.mVideoQuality != ImsStreamMediaProfile.VIDEO_QUALITY_NONE) { 1549ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mediaProfile.mVideoDirection = ImsStreamMediaProfile.DIRECTION_SEND_RECEIVE; 1550ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1551ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1552ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return mediaProfile; 1553ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1554ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1555ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private void enforceConversationMode() { 1556ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mInCall) { 1557ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mHold = false; 1558ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mUpdateRequest = UPDATE_NONE; 1559ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1560ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1561ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1562ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private void mergeInternal() { 15636804851b58264d7e82b09a845118d24d36c8d831Anthony Lee if (CONF_DBG) { 15646804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("mergeInternal :: "); 1565ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1566ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1567ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mSession.merge(); 1568ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mUpdateRequest = UPDATE_MERGE; 1569ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1570ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1571ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private void notifyConferenceSessionTerminated(ImsReasonInfo reasonInfo) { 15729bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn ImsCall.Listener listener = mListener; 1573ef36ef67e009449300b0150c60c9f637e205d79eWink Saville clear(reasonInfo); 1574ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1575ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (listener != null) { 1576ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 1577ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallTerminated(this, reasonInfo); 1578ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 1579ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("notifyConferenceSessionTerminated :: ", t); 1580ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1581ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1582ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1583ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1584ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private void notifyConferenceStateUpdated(ImsConferenceState state) { 15859e3452a8efa430f9ca04379be3da6baf0bb0f51aTyler Gunn if (state == null || state.mParticipants == null) { 15869e3452a8efa430f9ca04379be3da6baf0bb0f51aTyler Gunn return; 15879e3452a8efa430f9ca04379be3da6baf0bb0f51aTyler Gunn } 15889e3452a8efa430f9ca04379be3da6baf0bb0f51aTyler Gunn 15891c46760f9e523312d92e027dfdb52d359d65efe1Tyler Gunn Set<Entry<String, Bundle>> participants = state.mParticipants.entrySet(); 1590ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 15911c46760f9e523312d92e027dfdb52d359d65efe1Tyler Gunn if (participants == null) { 1592ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return; 1593ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1594ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 15951c46760f9e523312d92e027dfdb52d359d65efe1Tyler Gunn Iterator<Entry<String, Bundle>> iterator = participants.iterator(); 1596a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam mConferenceParticipants = new ArrayList<>(participants.size()); 1597ef36ef67e009449300b0150c60c9f637e205d79eWink Saville while (iterator.hasNext()) { 1598ef36ef67e009449300b0150c60c9f637e205d79eWink Saville Entry<String, Bundle> entry = iterator.next(); 1599ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1600ef36ef67e009449300b0150c60c9f637e205d79eWink Saville String key = entry.getKey(); 1601ef36ef67e009449300b0150c60c9f637e205d79eWink Saville Bundle confInfo = entry.getValue(); 1602ef36ef67e009449300b0150c60c9f637e205d79eWink Saville String status = confInfo.getString(ImsConferenceState.STATUS); 1603ef36ef67e009449300b0150c60c9f637e205d79eWink Saville String user = confInfo.getString(ImsConferenceState.USER); 16045965614f5b813f2739722589f84cec69c572b0a2Tyler Gunn String displayName = confInfo.getString(ImsConferenceState.DISPLAY_TEXT); 1605ef36ef67e009449300b0150c60c9f637e205d79eWink Saville String endpoint = confInfo.getString(ImsConferenceState.ENDPOINT); 1606ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 16076804851b58264d7e82b09a845118d24d36c8d831Anthony Lee if (CONF_DBG) { 16086804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("notifyConferenceStateUpdated :: key=" + key + 1609ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ", status=" + status + 1610ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ", user=" + user + 16115965614f5b813f2739722589f84cec69c572b0a2Tyler Gunn ", displayName= " + displayName + 1612ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ", endpoint=" + endpoint); 1613ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1614ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 16159bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn Uri handle = Uri.parse(user); 1616a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam if (endpoint == null) { 1617a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam endpoint = ""; 1618a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam } 16199bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn Uri endpointUri = Uri.parse(endpoint); 16209bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn int connectionState = ImsConferenceState.getConnectionStateForStatus(status); 1621ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1622a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam if (connectionState != Connection.STATE_DISCONNECTED) { 1623a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam ConferenceParticipant conferenceParticipant = new ConferenceParticipant(handle, 1624a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam displayName, endpointUri, connectionState); 1625a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam mConferenceParticipants.add(conferenceParticipant); 1626a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam } 1627ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 16281c46760f9e523312d92e027dfdb52d359d65efe1Tyler Gunn 16290f108033df343d446e42c403494cc2ab079895d5Anju Mathapati if (mConferenceParticipants != null && mListener != null) { 16301c46760f9e523312d92e027dfdb52d359d65efe1Tyler Gunn try { 1631a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam mListener.onConferenceParticipantsStateChanged(this, mConferenceParticipants); 16321c46760f9e523312d92e027dfdb52d359d65efe1Tyler Gunn } catch (Throwable t) { 16331c46760f9e523312d92e027dfdb52d359d65efe1Tyler Gunn loge("notifyConferenceStateUpdated :: ", t); 16341c46760f9e523312d92e027dfdb52d359d65efe1Tyler Gunn } 16351c46760f9e523312d92e027dfdb52d359d65efe1Tyler Gunn } 1636ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 1637ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 1638b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee /** 1639b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee * Perform all cleanup and notification around the termination of a session. 1640b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee * Note that there are 2 distinct modes of operation. The first is when 1641b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee * we receive a session termination on the primary session when we are 1642b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee * in the processing of merging. The second is when we are not merging anything 1643b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee * and the call is terminated. 1644b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee * 1645b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee * @param reasonInfo The reason for the session termination 1646b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee */ 1647b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee private void processCallTerminated(ImsReasonInfo reasonInfo) { 164895d563ed2a215d67a4f789c3ebb5a526fb95cc7fTyler Gunn logi("processCallTerminated :: reason=" + reasonInfo + " userInitiated = " + 164995d563ed2a215d67a4f789c3ebb5a526fb95cc7fTyler Gunn mTerminationRequestPending); 1650b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee 1651b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee ImsCall.Listener listener = null; 1652b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee synchronized(ImsCall.this) { 1653047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn // If we are in the midst of establishing a conference, we will bury the termination 165495d563ed2a215d67a4f789c3ebb5a526fb95cc7fTyler Gunn // until the merge has completed. If necessary we can surface the termination at 165595d563ed2a215d67a4f789c3ebb5a526fb95cc7fTyler Gunn // this point. 165695d563ed2a215d67a4f789c3ebb5a526fb95cc7fTyler Gunn // We will also NOT bury the termination if a termination was initiated locally. 165795d563ed2a215d67a4f789c3ebb5a526fb95cc7fTyler Gunn if (isCallSessionMergePending() && !mTerminationRequestPending) { 1658b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee // Since we are in the process of a merge, this trigger means something 1659b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee // else because it is probably due to the merge happening vs. the 1660b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee // session is really terminated. Let's flag this and revisit if 1661b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee // the merge() ends up failing because we will need to take action on the 1662b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee // mSession in that case since the termination was not due to the merge 1663b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee // succeeding. 16646804851b58264d7e82b09a845118d24d36c8d831Anthony Lee if (CONF_DBG) { 16656804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("processCallTerminated :: burying termination during ongoing merge."); 1666b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee } 1667b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee mSessionEndDuringMerge = true; 1668b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee mSessionEndDuringMergeReasonInfo = reasonInfo; 1669b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee return; 1670b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee } 1671b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee 16729bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn // If we are terminating the conference call, notify using conference listeners. 16739bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn if (isMultiparty()) { 1674b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee notifyConferenceSessionTerminated(reasonInfo); 16759bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn return; 1676b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee } else { 1677b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee listener = mListener; 1678b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee clear(reasonInfo); 1679b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee } 1680b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee } 1681b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee 1682b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee if (listener != null) { 1683b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee try { 1684b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee listener.onCallTerminated(ImsCall.this, reasonInfo); 1685b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee } catch (Throwable t) { 1686c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee loge("processCallTerminated :: ", t); 1687b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee } 1688b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee } 1689b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee } 169071382693cbc81b1d131085f52d97879976706f55Anthony Lee 169171382693cbc81b1d131085f52d97879976706f55Anthony Lee /** 169271382693cbc81b1d131085f52d97879976706f55Anthony Lee * This function determines if the ImsCallSession is our actual ImsCallSession or if is 169371382693cbc81b1d131085f52d97879976706f55Anthony Lee * the transient session used in the process of creating a conference. This function should only 169471382693cbc81b1d131085f52d97879976706f55Anthony Lee * be called within callbacks that are not directly related to conference merging but might 169571382693cbc81b1d131085f52d97879976706f55Anthony Lee * potentially still be called on the transient ImsCallSession sent to us from 169671382693cbc81b1d131085f52d97879976706f55Anthony Lee * callSessionMergeStarted() when we don't really care. In those situations, we probably don't 169771382693cbc81b1d131085f52d97879976706f55Anthony Lee * want to take any action so we need to know that we can return early. 169871382693cbc81b1d131085f52d97879976706f55Anthony Lee * 169971382693cbc81b1d131085f52d97879976706f55Anthony Lee * @param session - The {@link ImsCallSession} that the function needs to analyze 170071382693cbc81b1d131085f52d97879976706f55Anthony Lee * @return true if this is the transient {@link ImsCallSession}, false otherwise. 170171382693cbc81b1d131085f52d97879976706f55Anthony Lee */ 170271382693cbc81b1d131085f52d97879976706f55Anthony Lee private boolean isTransientConferenceSession(ImsCallSession session) { 170371382693cbc81b1d131085f52d97879976706f55Anthony Lee if (session != null && session != mSession && session == mTransientConferenceSession) { 170471382693cbc81b1d131085f52d97879976706f55Anthony Lee return true; 170571382693cbc81b1d131085f52d97879976706f55Anthony Lee } 170671382693cbc81b1d131085f52d97879976706f55Anthony Lee return false; 170771382693cbc81b1d131085f52d97879976706f55Anthony Lee } 170871382693cbc81b1d131085f52d97879976706f55Anthony Lee 1709c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee private void setTransientSessionAsPrimary(ImsCallSession transientSession) { 1710c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee synchronized (ImsCall.this) { 1711c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee mSession.setListener(null); 1712c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee mSession = transientSession; 1713c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee mSession.setListener(createCallSessionListener()); 1714c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } 1715c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } 1716c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee 1717818c09d7b55d3257e91e528749587349f7197e3fAnju Mathapati private void markCallAsMerged(boolean playDisconnectTone) { 1718818c09d7b55d3257e91e528749587349f7197e3fAnju Mathapati if (!isSessionAlive(mSession)) { 171995be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam // If the peer is dead, let's not play a disconnect sound for it when we 172095be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam // unbury the termination callback. 1721818c09d7b55d3257e91e528749587349f7197e3fAnju Mathapati logi("markCallAsMerged"); 1722818c09d7b55d3257e91e528749587349f7197e3fAnju Mathapati setIsMerged(playDisconnectTone); 1723818c09d7b55d3257e91e528749587349f7197e3fAnju Mathapati mSessionEndDuringMerge = true; 1724818c09d7b55d3257e91e528749587349f7197e3fAnju Mathapati String reasonInfo; 1725818c09d7b55d3257e91e528749587349f7197e3fAnju Mathapati if (playDisconnectTone) { 1726818c09d7b55d3257e91e528749587349f7197e3fAnju Mathapati reasonInfo = "Call ended by network"; 1727818c09d7b55d3257e91e528749587349f7197e3fAnju Mathapati } else { 1728818c09d7b55d3257e91e528749587349f7197e3fAnju Mathapati reasonInfo = "Call ended during conference merge process."; 1729818c09d7b55d3257e91e528749587349f7197e3fAnju Mathapati } 1730818c09d7b55d3257e91e528749587349f7197e3fAnju Mathapati mSessionEndDuringMergeReasonInfo = new ImsReasonInfo( 1731818c09d7b55d3257e91e528749587349f7197e3fAnju Mathapati ImsReasonInfo.CODE_UNSPECIFIED, 0, reasonInfo); 173295be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam } 173395be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam } 173495be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam 173571382693cbc81b1d131085f52d97879976706f55Anthony Lee /** 173695be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * Checks if the merge was requested by foreground conference call 173795be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * 173895be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * @return true if the merge was requested by foreground conference call 1739047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn */ 174095be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam public boolean isMergeRequestedByConf() { 174195be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam synchronized(mLockObj) { 174295be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam return mMergeRequestedByConference; 174395be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam } 174495be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam } 174595be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam 174695be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam /** 174795be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * Resets the flag which indicates merge request was sent by 174895be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * foreground conference call 174995be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam */ 175095be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam public void resetIsMergeRequestedByConf(boolean value) { 175195be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam synchronized(mLockObj) { 175295be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam mMergeRequestedByConference = value; 175395be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam } 175495be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam } 175595be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam 175695be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam /** 175795be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * Returns current ImsCallSession 175895be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * 175995be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * @return current session 176095be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam */ 176195be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam public ImsCallSession getSession() { 176295be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam synchronized(mLockObj) { 176395be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam return mSession; 1764c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } 1765047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn } 1766047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn 1767047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn /** 1768c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee * We have detected that a initial conference call has been fully configured. The internal 1769c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee * state of both {@code ImsCall} objects need to be cleaned up to reflect the new state. 1770c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee * This function should only be called in the context of the merge host to simplify logic 177171382693cbc81b1d131085f52d97879976706f55Anthony Lee * 177271382693cbc81b1d131085f52d97879976706f55Anthony Lee */ 1773b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee private void processMergeComplete() { 17746804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("processMergeComplete :: "); 1775c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee 1776c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // The logic simplifies if we can assume that this function is only called on 1777c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // the merge host. 1778c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee if (!isMergeHost()) { 1779c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee loge("processMergeComplete :: We are not the merge host!"); 1780c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee return; 1781b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee } 1782b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee 178371382693cbc81b1d131085f52d97879976706f55Anthony Lee ImsCall.Listener listener; 1784047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn boolean swapRequired = false; 17859bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn 178695be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam ImsCall finalHostCall; 178795be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam ImsCall finalPeerCall; 178895be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam 178995be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam synchronized(ImsCall.this) { 1790c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee if (isMultiparty()) { 1791c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee setIsMerged(false); 179295be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam // if case handles Case 4 explained in callSessionMergeComplete 179395be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam // otherwise it is case 5 179495be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam if (!mMergeRequestedByConference) { 179595be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam // single call in fg, conference call in bg. 179695be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam // Finally conf call becomes active after conference 179795be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam this.mHold = false; 179895be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam swapRequired = true; 1799047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn } 1800818c09d7b55d3257e91e528749587349f7197e3fAnju Mathapati mMergePeer.markCallAsMerged(false); 180195be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam finalHostCall = this; 180295be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam finalPeerCall = mMergePeer; 1803047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn } else { 1804c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // If we are here, we are not trying to merge a new call into an existing 1805c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // conference. That means that there is a transient session on the merge 1806c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // host that represents the future conference once all the parties 1807c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // have been added to it. So make sure that it exists or else something 1808c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // very wrong is going on. 1809c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee if (mTransientConferenceSession == null) { 1810c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee loge("processMergeComplete :: No transient session!"); 1811c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee return; 1812047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn } 1813c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee if (mMergePeer == null) { 1814c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee loge("processMergeComplete :: No merge peer!"); 1815c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee return; 1816047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn } 1817047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn 1818c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // Since we are the host, we have the transient session attached to us. Let's detach 1819c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // it and figure out where we need to set it for the final conference configuration. 1820c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee ImsCallSession transientConferenceSession = mTransientConferenceSession; 1821c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee mTransientConferenceSession = null; 1822c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee 1823c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // Clear the listener for this transient session, we'll create a new listener 1824c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // when it is attached to the final ImsCall that it should live on. 1825c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee transientConferenceSession.setListener(null); 1826c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee 1827c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // Determine which call the transient session should be moved to. If the current 1828c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // call session is still alive and the merge peer's session is not, we have a 1829c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // situation where the current call failed to merge into the conference but the 1830c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // merge peer did merge in to the conference. In this type of scenario the current 1831c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // call will continue as a single party call, yet the background call will become 1832c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // the conference. 1833c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee 183495be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam // handles Case 3 explained in callSessionMergeComplete 1835c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee if (isSessionAlive(mSession) && !isSessionAlive(mMergePeer.getCallSession())) { 1836c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // I'm the host but we are moving the transient session to the peer since its 1837c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // session was disconnected and my session is still alive. This signifies that 1838c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // their session was properly added to the conference but mine was not because 1839c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // it is probably in the held state as opposed to part of the final conference. 1840c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // In this case, we need to set isMerged to false on both calls so the 1841c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // disconnect sound is called when either call disconnects. 1842c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // Note that this case is only valid if this is an initial conference being 1843c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // brought up. 184495be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam mMergePeer.mHold = false; 184595be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam this.mHold = true; 1846d0fb66402074528deccd6a85f3d1eca8d2d0714fAnju Mathapati if (mConferenceParticipants != null && !mConferenceParticipants.isEmpty()) { 1847d0fb66402074528deccd6a85f3d1eca8d2d0714fAnju Mathapati mMergePeer.mConferenceParticipants = mConferenceParticipants; 1848d0fb66402074528deccd6a85f3d1eca8d2d0714fAnju Mathapati } 1849d0fb66402074528deccd6a85f3d1eca8d2d0714fAnju Mathapati // At this point both host & peer will have participant information. 1850d0fb66402074528deccd6a85f3d1eca8d2d0714fAnju Mathapati // Peer will transition to host & the participant information 1851d0fb66402074528deccd6a85f3d1eca8d2d0714fAnju Mathapati // from that will be used 1852d0fb66402074528deccd6a85f3d1eca8d2d0714fAnju Mathapati // HostCall that failed to merge will remain as a single call with 1853d0fb66402074528deccd6a85f3d1eca8d2d0714fAnju Mathapati // mConferenceParticipants, which should not be used. 1854d0fb66402074528deccd6a85f3d1eca8d2d0714fAnju Mathapati // Expectation is that if this call becomes part of a conference call in future, 1855d0fb66402074528deccd6a85f3d1eca8d2d0714fAnju Mathapati // mConferenceParticipants will be overriten with new CEP that is received. 1856c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee finalHostCall = mMergePeer; 1857c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee finalPeerCall = this; 1858c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee swapRequired = true; 1859c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee setIsMerged(false); 1860c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee mMergePeer.setIsMerged(false); 18616804851b58264d7e82b09a845118d24d36c8d831Anthony Lee if (CONF_DBG) { 18626804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("processMergeComplete :: transient will transfer to merge peer"); 1863047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn } 18646804851b58264d7e82b09a845118d24d36c8d831Anthony Lee } else if (!isSessionAlive(mSession) && 18656804851b58264d7e82b09a845118d24d36c8d831Anthony Lee isSessionAlive(mMergePeer.getCallSession())) { 186695be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam // Handles case 2 explained in callSessionMergeComplete 1867c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // The transient session stays with us and the disconnect sound should be played 1868c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // when the merge peer eventually disconnects since it was not actually added to 1869c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // the conference and is probably sitting in the held state. 1870c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee finalHostCall = this; 1871c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee finalPeerCall = mMergePeer; 1872c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee swapRequired = false; 1873c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee setIsMerged(false); 1874c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee mMergePeer.setIsMerged(false); // Play the disconnect sound 18756804851b58264d7e82b09a845118d24d36c8d831Anthony Lee if (CONF_DBG) { 18766804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("processMergeComplete :: transient will stay with the merge host"); 1877c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } 1878c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } else { 187995be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam // Handles case 1 explained in callSessionMergeComplete 1880c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // The transient session stays with us and the disconnect sound should not be 1881c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // played when we ripple up the disconnect for the merge peer because it was 1882c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // only disconnected to be added to the conference. 1883c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee finalHostCall = this; 1884c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee finalPeerCall = mMergePeer; 1885818c09d7b55d3257e91e528749587349f7197e3fAnju Mathapati mMergePeer.markCallAsMerged(false); 1886c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee swapRequired = false; 1887c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee setIsMerged(false); 1888c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee mMergePeer.setIsMerged(true); 18896804851b58264d7e82b09a845118d24d36c8d831Anthony Lee if (CONF_DBG) { 18906804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("processMergeComplete :: transient will stay with us (I'm the host)."); 1891047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn } 1892047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn } 1893047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn 18946804851b58264d7e82b09a845118d24d36c8d831Anthony Lee if (CONF_DBG) { 18956804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("processMergeComplete :: call=" + finalHostCall + " is the final host"); 1896c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } 1897c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee 1898c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // Add the transient session to the ImsCall that ended up being the host for the 1899c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // conference. 1900c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee finalHostCall.setTransientSessionAsPrimary(transientConferenceSession); 1901047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn } 1902047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn 1903c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee listener = finalHostCall.mListener; 1904c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee 19051c1088887347d682b7b186027d98ad3617dcfb68Anju Mathapati updateCallProfile(finalPeerCall); 19061c1088887347d682b7b186027d98ad3617dcfb68Anju Mathapati updateCallProfile(finalHostCall); 19071c1088887347d682b7b186027d98ad3617dcfb68Anju Mathapati 1908c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // Clear all the merge related flags. 1909c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee clearMergeInfo(); 1910c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee 1911c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // For the final peer...let's bubble up any possible disconnects that we had 1912c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // during the merge process 1913c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee finalPeerCall.notifySessionTerminatedDuringMerge(); 1914c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // For the final host, let's just bury the disconnects that we my have received 1915c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // during the merge process since we are now the host of the conference call. 1916c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee finalHostCall.clearSessionTerminationFlags(); 191725394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn 191825394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn // Keep track of the fact that merge host is the origin of a conference call in 191925394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn // progress. This is important so that we can later determine if a multiparty ImsCall 192025394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn // is multiparty because it was the origin of a conference call, or because it is a 192125394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn // member of a conference on another device. 192225394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn finalHostCall.mIsConferenceHost = true; 192371382693cbc81b1d131085f52d97879976706f55Anthony Lee } 192471382693cbc81b1d131085f52d97879976706f55Anthony Lee if (listener != null) { 192571382693cbc81b1d131085f52d97879976706f55Anthony Lee try { 192695be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam // finalPeerCall will have the participant that was not merged and 192795be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam // it will be held state 192895be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam // if peer was merged successfully, finalPeerCall will be null 192995be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam listener.onCallMerged(finalHostCall, finalPeerCall, swapRequired); 193071382693cbc81b1d131085f52d97879976706f55Anthony Lee } catch (Throwable t) { 1931b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee loge("processMergeComplete :: ", t); 193271382693cbc81b1d131085f52d97879976706f55Anthony Lee } 19336c0b0d0e83b8d06f40ec814573adc69f362704a9Tyler Gunn if (mConferenceParticipants != null && !mConferenceParticipants.isEmpty()) { 1934a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam try { 1935d0fb66402074528deccd6a85f3d1eca8d2d0714fAnju Mathapati listener.onConferenceParticipantsStateChanged(finalHostCall, 1936d0fb66402074528deccd6a85f3d1eca8d2d0714fAnju Mathapati mConferenceParticipants); 1937a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam } catch (Throwable t) { 1938a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam loge("processMergeComplete :: ", t); 1939a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam } 1940a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam } 194171382693cbc81b1d131085f52d97879976706f55Anthony Lee } 194271382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 194371382693cbc81b1d131085f52d97879976706f55Anthony Lee } 194471382693cbc81b1d131085f52d97879976706f55Anthony Lee 19451c1088887347d682b7b186027d98ad3617dcfb68Anju Mathapati private static void updateCallProfile(ImsCall call) { 19461c1088887347d682b7b186027d98ad3617dcfb68Anju Mathapati if (call != null) { 19471c1088887347d682b7b186027d98ad3617dcfb68Anju Mathapati call.updateCallProfile(); 19481c1088887347d682b7b186027d98ad3617dcfb68Anju Mathapati } 19491c1088887347d682b7b186027d98ad3617dcfb68Anju Mathapati } 19501c1088887347d682b7b186027d98ad3617dcfb68Anju Mathapati 19511c1088887347d682b7b186027d98ad3617dcfb68Anju Mathapati private void updateCallProfile() { 19521c1088887347d682b7b186027d98ad3617dcfb68Anju Mathapati synchronized (mLockObj) { 19531c1088887347d682b7b186027d98ad3617dcfb68Anju Mathapati if (mSession != null) { 19541c1088887347d682b7b186027d98ad3617dcfb68Anju Mathapati mCallProfile = mSession.getCallProfile(); 19551c1088887347d682b7b186027d98ad3617dcfb68Anju Mathapati } 19561c1088887347d682b7b186027d98ad3617dcfb68Anju Mathapati } 19571c1088887347d682b7b186027d98ad3617dcfb68Anju Mathapati } 19581c1088887347d682b7b186027d98ad3617dcfb68Anju Mathapati 195971382693cbc81b1d131085f52d97879976706f55Anthony Lee /** 1960047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn * Handles the case where the session has ended during a merge by reporting the termination 1961047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn * reason to listeners. 1962047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn */ 1963047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn private void notifySessionTerminatedDuringMerge() { 1964047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn ImsCall.Listener listener; 1965047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn boolean notifyFailure = false; 1966047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn ImsReasonInfo notifyFailureReasonInfo = null; 1967047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn 1968047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn synchronized(ImsCall.this) { 1969047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn listener = mListener; 1970047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn if (mSessionEndDuringMerge) { 1971047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn // Set some local variables that will send out a notification about a 1972047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn // previously buried termination callback for our primary session now that 1973047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn // we know that this is not due to the conference call merging successfully. 19746804851b58264d7e82b09a845118d24d36c8d831Anthony Lee if (CONF_DBG) { 19756804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("notifySessionTerminatedDuringMerge ::reporting terminate during merge"); 1976047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn } 1977047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn notifyFailure = true; 1978047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn notifyFailureReasonInfo = mSessionEndDuringMergeReasonInfo; 1979047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn } 1980c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee clearSessionTerminationFlags(); 1981047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn } 1982047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn 1983047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn if (listener != null && notifyFailure) { 1984047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn try { 1985047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn processCallTerminated(notifyFailureReasonInfo); 1986047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn } catch (Throwable t) { 1987047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn loge("notifySessionTerminatedDuringMerge :: ", t); 1988047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn } 1989047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn } 1990047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn } 1991047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn 1992c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee private void clearSessionTerminationFlags() { 1993c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee mSessionEndDuringMerge = false; 1994c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee mSessionEndDuringMergeReasonInfo = null; 1995c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } 1996c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee 1997a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam /** 199871382693cbc81b1d131085f52d97879976706f55Anthony Lee * We received a callback from ImsCallSession that a merge failed. Clean up all 1999c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee * internal state to represent this state change. The calling function is a callback 2000c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee * and should have been called on the session that was in the foreground 2001c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee * when merge() was originally called. It is assumed that this function will be called 2002c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee * on the merge host. 200371382693cbc81b1d131085f52d97879976706f55Anthony Lee * 200471382693cbc81b1d131085f52d97879976706f55Anthony Lee * @param reasonInfo The {@link ImsReasonInfo} why the merge failed. 200571382693cbc81b1d131085f52d97879976706f55Anthony Lee */ 2006b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee private void processMergeFailed(ImsReasonInfo reasonInfo) { 20076804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("processMergeFailed :: reason=" + reasonInfo); 2008047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn 2009047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn ImsCall.Listener listener; 201071382693cbc81b1d131085f52d97879976706f55Anthony Lee synchronized(ImsCall.this) { 2011c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // The logic simplifies if we can assume that this function is only called on 2012c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // the merge host. 2013c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee if (!isMergeHost()) { 2014c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee loge("processMergeFailed :: We are not the merge host!"); 2015c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee return; 2016c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } 2017c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee 201861d41c1f9ba249bd0df575cc1b551a9e70f54645Anthony Lee // Try to clean up the transient session if it exists. 201961d41c1f9ba249bd0df575cc1b551a9e70f54645Anthony Lee if (mTransientConferenceSession != null) { 202071382693cbc81b1d131085f52d97879976706f55Anthony Lee mTransientConferenceSession.setListener(null); 202171382693cbc81b1d131085f52d97879976706f55Anthony Lee mTransientConferenceSession = null; 2022b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee } 2023047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn 2024c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee listener = mListener; 2025c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee 202661d41c1f9ba249bd0df575cc1b551a9e70f54645Anthony Lee // Ensure the calls being conferenced into the conference has isMerged = false. 2027c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // Ensure any terminations are surfaced from this session. 2028818c09d7b55d3257e91e528749587349f7197e3fAnju Mathapati markCallAsMerged(true); 2029818c09d7b55d3257e91e528749587349f7197e3fAnju Mathapati setCallSessionMergePending(false); 2030c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee notifySessionTerminatedDuringMerge(); 203161d41c1f9ba249bd0df575cc1b551a9e70f54645Anthony Lee 2032818c09d7b55d3257e91e528749587349f7197e3fAnju Mathapati // Perform the same cleanup on the merge peer if it exists. 203361d41c1f9ba249bd0df575cc1b551a9e70f54645Anthony Lee if (mMergePeer != null) { 2034818c09d7b55d3257e91e528749587349f7197e3fAnju Mathapati mMergePeer.markCallAsMerged(true); 2035818c09d7b55d3257e91e528749587349f7197e3fAnju Mathapati mMergePeer.setCallSessionMergePending(false); 203661d41c1f9ba249bd0df575cc1b551a9e70f54645Anthony Lee mMergePeer.notifySessionTerminatedDuringMerge(); 203761d41c1f9ba249bd0df575cc1b551a9e70f54645Anthony Lee } else { 203861d41c1f9ba249bd0df575cc1b551a9e70f54645Anthony Lee loge("processMergeFailed :: No merge peer!"); 203961d41c1f9ba249bd0df575cc1b551a9e70f54645Anthony Lee } 2040c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee 2041c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // Clear all the various flags around coordinating this merge. 2042c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee clearMergeInfo(); 204371382693cbc81b1d131085f52d97879976706f55Anthony Lee } 204471382693cbc81b1d131085f52d97879976706f55Anthony Lee if (listener != null) { 204571382693cbc81b1d131085f52d97879976706f55Anthony Lee try { 204671382693cbc81b1d131085f52d97879976706f55Anthony Lee listener.onCallMergeFailed(ImsCall.this, reasonInfo); 204771382693cbc81b1d131085f52d97879976706f55Anthony Lee } catch (Throwable t) { 2048b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee loge("processMergeFailed :: ", t); 204971382693cbc81b1d131085f52d97879976706f55Anthony Lee } 205071382693cbc81b1d131085f52d97879976706f55Anthony Lee } 2051c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee 205271382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 205371382693cbc81b1d131085f52d97879976706f55Anthony Lee } 205471382693cbc81b1d131085f52d97879976706f55Anthony Lee 2055ef36ef67e009449300b0150c60c9f637e205d79eWink Saville private class ImsCallSessionListenerProxy extends ImsCallSession.Listener { 2056ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 205771382693cbc81b1d131085f52d97879976706f55Anthony Lee public void callSessionProgressing(ImsCallSession session, ImsStreamMediaProfile profile) { 20586804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionProgressing :: session=" + session + " profile=" + profile); 20596804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 206071382693cbc81b1d131085f52d97879976706f55Anthony Lee if (isTransientConferenceSession(session)) { 2061c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // If it is a transient (conference) session, there is no action for this signal. 20626804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionProgressing :: not supported for transient conference session=" + 2063b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee session); 206471382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 206571382693cbc81b1d131085f52d97879976706f55Anthony Lee } 206671382693cbc81b1d131085f52d97879976706f55Anthony Lee 2067ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall.Listener listener; 2068ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2069ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(ImsCall.this) { 2070ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener = mListener; 2071ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mCallProfile.mMediaProfile.copyFrom(profile); 2072ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2073ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2074ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (listener != null) { 2075ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 2076ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallProgressing(ImsCall.this); 2077ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 2078ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("callSessionProgressing :: ", t); 2079ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2080ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2081ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2082ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2083ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 208471382693cbc81b1d131085f52d97879976706f55Anthony Lee public void callSessionStarted(ImsCallSession session, ImsCallProfile profile) { 20856804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionStarted :: session=" + session + " profile=" + profile); 2086c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee 2087c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee if (!isTransientConferenceSession(session)) { 2088c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // In the case that we are in the middle of a merge (either host or peer), we have 2089c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // closure as far as this call's primary session is concerned. If we are not 2090c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // merging...its a NOOP. 2091c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee setCallSessionMergePending(false); 2092c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } else { 20936804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionStarted :: on transient session=" + session); 2094c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee return; 2095ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2096ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2097c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee if (isTransientConferenceSession(session)) { 2098c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // No further processing is needed if this is the transient session. 2099b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee return; 2100b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee } 2101b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee 2102ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall.Listener listener; 2103ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2104ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(ImsCall.this) { 2105ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener = mListener; 2106ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mCallProfile = profile; 2107ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2108ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2109ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (listener != null) { 2110ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 2111ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallStarted(ImsCall.this); 2112ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 2113ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("callSessionStarted :: ", t); 2114ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2115ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2116ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2117ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2118ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 211971382693cbc81b1d131085f52d97879976706f55Anthony Lee public void callSessionStartFailed(ImsCallSession session, ImsReasonInfo reasonInfo) { 21206804851b58264d7e82b09a845118d24d36c8d831Anthony Lee loge("callSessionStartFailed :: session=" + session + " reasonInfo=" + reasonInfo); 21216804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 212271382693cbc81b1d131085f52d97879976706f55Anthony Lee if (isTransientConferenceSession(session)) { 2123c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // We should not get this callback for a transient session. 21246804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionStartFailed :: not supported for transient conference session=" + 2125b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee session); 212671382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 212771382693cbc81b1d131085f52d97879976706f55Anthony Lee } 212871382693cbc81b1d131085f52d97879976706f55Anthony Lee 2129ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall.Listener listener; 2130ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2131ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(ImsCall.this) { 2132ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener = mListener; 2133ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mLastReasonInfo = reasonInfo; 2134ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2135ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2136ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (listener != null) { 2137ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 2138ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallStartFailed(ImsCall.this, reasonInfo); 2139ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 2140ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("callSessionStarted :: ", t); 2141ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2142ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2143ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2144ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2145ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 214671382693cbc81b1d131085f52d97879976706f55Anthony Lee public void callSessionTerminated(ImsCallSession session, ImsReasonInfo reasonInfo) { 21476804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionTerminated :: session=" + session + " reasonInfo=" + reasonInfo); 21486804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 2149c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee if (isTransientConferenceSession(session)) { 21506804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionTerminated :: on transient session=" + session); 2151c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // This is bad, it should be treated much a callSessionMergeFailed since the 2152c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // transient session only exists when in the process of a merge and the 2153c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // termination of this session is effectively the end of the merge. 2154c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee processMergeFailed(reasonInfo); 215571382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 215671382693cbc81b1d131085f52d97879976706f55Anthony Lee } 215771382693cbc81b1d131085f52d97879976706f55Anthony Lee 2158c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // Process the termination first. If we are in the midst of establishing a conference 2159c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // call, we may bury this callback until we are done. If there so no conference 2160c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // call, the code after this function will be a NOOP. 2161c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee processCallTerminated(reasonInfo); 2162c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee 2163047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn // If session has terminated, it is no longer pending merge. 2164047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn setCallSessionMergePending(false); 2165047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn 2166ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2167ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2168ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 216971382693cbc81b1d131085f52d97879976706f55Anthony Lee public void callSessionHeld(ImsCallSession session, ImsCallProfile profile) { 21706804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionHeld :: session=" + session + "profile=" + profile); 2171ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall.Listener listener; 2172ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2173ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(ImsCall.this) { 2174047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn // If the session was held, it is no longer pending a merge -- this means it could 2175047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn // not be merged into the conference and was held instead. 2176047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn setCallSessionMergePending(false); 2177047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn 2178ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mCallProfile = profile; 2179ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2180ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mUpdateRequest == UPDATE_HOLD_MERGE) { 2181c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // This hold request was made to set the stage for a merge. 2182ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mergeInternal(); 2183ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return; 2184ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2185ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2186ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mUpdateRequest = UPDATE_NONE; 2187ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener = mListener; 2188ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2189ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2190ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (listener != null) { 2191ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 2192ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallHeld(ImsCall.this); 2193ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 2194ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("callSessionHeld :: ", t); 2195ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2196ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2197ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2198ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2199ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 220071382693cbc81b1d131085f52d97879976706f55Anthony Lee public void callSessionHoldFailed(ImsCallSession session, ImsReasonInfo reasonInfo) { 22016804851b58264d7e82b09a845118d24d36c8d831Anthony Lee loge("callSessionHoldFailed :: session" + session + "reasonInfo=" + reasonInfo); 22026804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 220371382693cbc81b1d131085f52d97879976706f55Anthony Lee if (isTransientConferenceSession(session)) { 2204c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // We should not get this callback for a transient session. 22056804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionHoldFailed :: not supported for transient conference session=" + 2206b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee session); 220771382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 220871382693cbc81b1d131085f52d97879976706f55Anthony Lee } 220971382693cbc81b1d131085f52d97879976706f55Anthony Lee 2210d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh logi("callSessionHoldFailed :: session=" + session + 2211d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh ", reasonInfo=" + reasonInfo); 2212d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh 2213d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh synchronized (mLockObj) { 2214a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam mHold = false; 2215a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam } 2216a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam 2217ef36ef67e009449300b0150c60c9f637e205d79eWink Saville boolean isHoldForMerge = false; 2218ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall.Listener listener; 2219ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2220ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(ImsCall.this) { 2221ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (mUpdateRequest == UPDATE_HOLD_MERGE) { 2222ef36ef67e009449300b0150c60c9f637e205d79eWink Saville isHoldForMerge = true; 2223ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2224ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2225ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mUpdateRequest = UPDATE_NONE; 2226ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener = mListener; 2227ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2228ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2229ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (listener != null) { 2230ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 2231ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallHoldFailed(ImsCall.this, reasonInfo); 2232ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 2233ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("callSessionHoldFailed :: ", t); 2234ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2235ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2236ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2237ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2238ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 223971382693cbc81b1d131085f52d97879976706f55Anthony Lee public void callSessionHoldReceived(ImsCallSession session, ImsCallProfile profile) { 22406804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionHoldReceived :: session=" + session + "profile=" + profile); 22416804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 224271382693cbc81b1d131085f52d97879976706f55Anthony Lee if (isTransientConferenceSession(session)) { 2243c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // We should not get this callback for a transient session. 22446804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionHoldReceived :: not supported for transient conference session=" + 2245b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee session); 224671382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 224771382693cbc81b1d131085f52d97879976706f55Anthony Lee } 224871382693cbc81b1d131085f52d97879976706f55Anthony Lee 2249ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall.Listener listener; 2250ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2251ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(ImsCall.this) { 2252ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener = mListener; 2253ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mCallProfile = profile; 2254ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2255ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2256ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (listener != null) { 2257ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 2258ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallHoldReceived(ImsCall.this); 2259ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 2260ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("callSessionHoldReceived :: ", t); 2261ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2262ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2263ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2264ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2265ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 226671382693cbc81b1d131085f52d97879976706f55Anthony Lee public void callSessionResumed(ImsCallSession session, ImsCallProfile profile) { 22676804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionResumed :: session=" + session + "profile=" + profile); 22686804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 226971382693cbc81b1d131085f52d97879976706f55Anthony Lee if (isTransientConferenceSession(session)) { 22706804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionResumed :: not supported for transient conference session=" + 2271b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee session); 227271382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 227371382693cbc81b1d131085f52d97879976706f55Anthony Lee } 227471382693cbc81b1d131085f52d97879976706f55Anthony Lee 2275c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // If this call was pending a merge, it is not anymore. This is the case when we 2276c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // are merging in a new call into an existing conference. 2277c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee setCallSessionMergePending(false); 2278c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee 2279c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // TOOD: When we are merging a new call into an existing conference we are waiting 2280c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // for 2 triggers to let us know that the conference has been established, the first 2281c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // is a termination for the new calls (since it is added to the conference) the second 2282c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // would be a resume on the existing conference. If the resume comes first, then 2283c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // we will make the onCallResumed() callback and its unclear how this will behave if 2284c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // the termination has not come yet. 2285ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2286c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee ImsCall.Listener listener; 2287ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(ImsCall.this) { 2288ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener = mListener; 2289ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mCallProfile = profile; 2290ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mUpdateRequest = UPDATE_NONE; 2291095839a66699a128c76cd5002459fcba7c3a9a0dUma Maheswari Ramalingam mHold = false; 2292ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2293ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2294ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (listener != null) { 2295ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 2296ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallResumed(ImsCall.this); 2297ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 2298ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("callSessionResumed :: ", t); 2299ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2300ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2301ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2302ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2303ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 230471382693cbc81b1d131085f52d97879976706f55Anthony Lee public void callSessionResumeFailed(ImsCallSession session, ImsReasonInfo reasonInfo) { 23056804851b58264d7e82b09a845118d24d36c8d831Anthony Lee loge("callSessionResumeFailed :: session=" + session + "reasonInfo=" + reasonInfo); 23066804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 230771382693cbc81b1d131085f52d97879976706f55Anthony Lee if (isTransientConferenceSession(session)) { 23086804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionResumeFailed :: not supported for transient conference session=" + 2309b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee session); 231071382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 231171382693cbc81b1d131085f52d97879976706f55Anthony Lee } 231271382693cbc81b1d131085f52d97879976706f55Anthony Lee 2313a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam synchronized(mLockObj) { 2314a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam mHold = true; 2315a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam } 2316a1ed7b0957567367d0e782ee6ce1db265d028eceUma Maheswari Ramalingam 2317ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall.Listener listener; 2318ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2319ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(ImsCall.this) { 2320ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener = mListener; 2321ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mUpdateRequest = UPDATE_NONE; 2322ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2323ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2324ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (listener != null) { 2325ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 2326ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallResumeFailed(ImsCall.this, reasonInfo); 2327ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 2328ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("callSessionResumeFailed :: ", t); 2329ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2330ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2331ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2332ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2333ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 233471382693cbc81b1d131085f52d97879976706f55Anthony Lee public void callSessionResumeReceived(ImsCallSession session, ImsCallProfile profile) { 23356804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionResumeReceived :: session=" + session + "profile=" + profile); 23366804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 233771382693cbc81b1d131085f52d97879976706f55Anthony Lee if (isTransientConferenceSession(session)) { 23386804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionResumeReceived :: not supported for transient conference session=" + 2339b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee session); 234071382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 234171382693cbc81b1d131085f52d97879976706f55Anthony Lee } 234271382693cbc81b1d131085f52d97879976706f55Anthony Lee 2343ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall.Listener listener; 2344ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2345ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(ImsCall.this) { 2346ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener = mListener; 2347ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mCallProfile = profile; 2348ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2349ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2350ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (listener != null) { 2351ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 2352ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallResumeReceived(ImsCall.this); 2353ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 2354ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("callSessionResumeReceived :: ", t); 2355ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2356ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2357ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2358ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2359ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 23603f2b0aaa277545886571cbf90fc90fd5d304e714Tyler Gunn public void callSessionMergeStarted(ImsCallSession session, 2361ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCallSession newSession, ImsCallProfile profile) { 23626804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionMergeStarted :: session=" + session + " newSession=" + newSession + 23636804851b58264d7e82b09a845118d24d36c8d831Anthony Lee ", profile=" + profile); 2364ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 236571382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 2366ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2367ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 236895be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam /* 236995be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * This method check if session exists as a session on the current 237095be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * ImsCall or its counterpart if it is in the process of a conference 237195be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam */ 237295be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam private boolean doesCallSessionExistsInMerge(ImsCallSession cs) { 237395be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam String callId = cs.getCallId(); 237495be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam return ((isMergeHost() && Objects.equals(mMergePeer.mSession.getCallId(), callId)) || 237595be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam (isMergePeer() && Objects.equals(mMergeHost.mSession.getCallId(), callId)) || 237695be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam Objects.equals(mSession.getCallId(), callId)); 237795be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam } 237895be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam 237995be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam /** 238095be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * We received a callback from ImsCallSession that merge completed. 2381d9ed874439293ed6c34ce27a3689711c986f977bAnju Mathapati * @param newSession - this session can have 2 values based on the below scenarios 238295be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * 238395be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * Conference Scenarios : 238495be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * Case 1 - 3 way success case 238595be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * Case 2 - 3 way success case but held call fails to merge 238695be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * Case 3 - 3 way success case but active call fails to merge 238795be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * case 4 - 4 way success case, where merge is initiated on the foreground single-party 238895be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * call and the conference (mergeHost) is the background call. 238995be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * case 5 - 4 way success case, where merge is initiated on the foreground conference 239095be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * call (mergeHost) and the single party call is in the background. 239195be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * 239295be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam * Conference Result: 2393d9ed874439293ed6c34ce27a3689711c986f977bAnju Mathapati * session : new session after conference 2394d9ed874439293ed6c34ce27a3689711c986f977bAnju Mathapati * newSession = new session for case 1, 2, 3. 2395d9ed874439293ed6c34ce27a3689711c986f977bAnju Mathapati * Should be considered as mTransientConferencession 2396d9ed874439293ed6c34ce27a3689711c986f977bAnju Mathapati * newSession = Active conference session for case 5 will be null 2397d9ed874439293ed6c34ce27a3689711c986f977bAnju Mathapati * mergehost was foreground call 2398d9ed874439293ed6c34ce27a3689711c986f977bAnju Mathapati * mTransientConferencession will be null 2399d9ed874439293ed6c34ce27a3689711c986f977bAnju Mathapati * newSession = Active conference session for case 4 will be null 2400d9ed874439293ed6c34ce27a3689711c986f977bAnju Mathapati * mergeHost was background call 2401d9ed874439293ed6c34ce27a3689711c986f977bAnju Mathapati * mTransientConferencession will be null 240295be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam */ 2403ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 2404d9ed874439293ed6c34ce27a3689711c986f977bAnju Mathapati public void callSessionMergeComplete(ImsCallSession newSession) { 2405d9ed874439293ed6c34ce27a3689711c986f977bAnju Mathapati logi("callSessionMergeComplete :: newSession =" + newSession); 240695be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam if (!isMergeHost()) { 240795be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam // Handles case 4 240895be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam mMergeHost.processMergeComplete(); 240995be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam } else { 2410d9ed874439293ed6c34ce27a3689711c986f977bAnju Mathapati // Handles case 1, 2, 3 2411d9ed874439293ed6c34ce27a3689711c986f977bAnju Mathapati if (newSession != null) { 2412d9ed874439293ed6c34ce27a3689711c986f977bAnju Mathapati mTransientConferenceSession = doesCallSessionExistsInMerge(newSession) ? 2413d9ed874439293ed6c34ce27a3689711c986f977bAnju Mathapati null: newSession; 2414d9ed874439293ed6c34ce27a3689711c986f977bAnju Mathapati } 2415d9ed874439293ed6c34ce27a3689711c986f977bAnju Mathapati // Handles case 5 241695be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam processMergeComplete(); 241795be7c68495a3a22c45b8d7867bf5c0246513adbUma Maheswari Ramalingam } 24183f2b0aaa277545886571cbf90fc90fd5d304e714Tyler Gunn } 24193f2b0aaa277545886571cbf90fc90fd5d304e714Tyler Gunn 24203f2b0aaa277545886571cbf90fc90fd5d304e714Tyler Gunn @Override 242171382693cbc81b1d131085f52d97879976706f55Anthony Lee public void callSessionMergeFailed(ImsCallSession session, ImsReasonInfo reasonInfo) { 24226804851b58264d7e82b09a845118d24d36c8d831Anthony Lee loge("callSessionMergeFailed :: session=" + session + "reasonInfo=" + reasonInfo); 2423c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee 2424c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // Its possible that there could be threading issues with the other thread handling 2425c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // the other call. This could affect our state. 2426c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee synchronized (ImsCall.this) { 2427c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // Let's tell our parent ImsCall that the merge has failed and we need to clean 2428c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // up any temporary, transient state. Note this only gets called for an initial 2429c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // conference. If a merge into an existing conference fails, the two sessions will 2430c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // just go back to their original state (ACTIVE or HELD). 2431c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee if (isMergeHost()) { 2432c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee processMergeFailed(reasonInfo); 2433c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } else if (mMergeHost != null) { 2434c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee mMergeHost.processMergeFailed(reasonInfo); 2435c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } else { 2436c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee loge("callSessionMergeFailed :: No merge host for this conference!"); 2437c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } 2438ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2439ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2440ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2441ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 244271382693cbc81b1d131085f52d97879976706f55Anthony Lee public void callSessionUpdated(ImsCallSession session, ImsCallProfile profile) { 24436804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionUpdated :: session=" + session + " profile=" + profile); 24446804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 244571382693cbc81b1d131085f52d97879976706f55Anthony Lee if (isTransientConferenceSession(session)) { 24466804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionUpdated :: not supported for transient conference session=" + 2447b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee session); 244871382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 244971382693cbc81b1d131085f52d97879976706f55Anthony Lee } 245071382693cbc81b1d131085f52d97879976706f55Anthony Lee 2451ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall.Listener listener; 2452ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2453ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(ImsCall.this) { 2454ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener = mListener; 2455ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mCallProfile = profile; 2456ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2457ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2458ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (listener != null) { 2459ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 2460ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallUpdated(ImsCall.this); 2461ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 2462ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("callSessionUpdated :: ", t); 2463ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2464ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2465ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2466ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2467ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 246871382693cbc81b1d131085f52d97879976706f55Anthony Lee public void callSessionUpdateFailed(ImsCallSession session, ImsReasonInfo reasonInfo) { 24696804851b58264d7e82b09a845118d24d36c8d831Anthony Lee loge("callSessionUpdateFailed :: session=" + session + " reasonInfo=" + reasonInfo); 24706804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 247171382693cbc81b1d131085f52d97879976706f55Anthony Lee if (isTransientConferenceSession(session)) { 24726804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionUpdateFailed :: not supported for transient conference session=" + 2473b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee session); 247471382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 247571382693cbc81b1d131085f52d97879976706f55Anthony Lee } 247671382693cbc81b1d131085f52d97879976706f55Anthony Lee 2477ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall.Listener listener; 2478ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2479ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(ImsCall.this) { 2480ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener = mListener; 2481ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mUpdateRequest = UPDATE_NONE; 2482ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2483ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2484ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (listener != null) { 2485ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 2486ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallUpdateFailed(ImsCall.this, reasonInfo); 2487ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 2488ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("callSessionUpdateFailed :: ", t); 2489ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2490ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2491ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2492ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2493ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 249471382693cbc81b1d131085f52d97879976706f55Anthony Lee public void callSessionUpdateReceived(ImsCallSession session, ImsCallProfile profile) { 24956804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionUpdateReceived :: session=" + session + " profile=" + profile); 24966804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 249771382693cbc81b1d131085f52d97879976706f55Anthony Lee if (isTransientConferenceSession(session)) { 24986804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionUpdateReceived :: not supported for transient conference " + 2499b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee "session=" + session); 250071382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 250171382693cbc81b1d131085f52d97879976706f55Anthony Lee } 250271382693cbc81b1d131085f52d97879976706f55Anthony Lee 2503ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall.Listener listener; 2504ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2505ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(ImsCall.this) { 2506ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener = mListener; 2507ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mProposedCallProfile = profile; 2508ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mUpdateRequest = UPDATE_UNSPECIFIED; 2509ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2510ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2511ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (listener != null) { 2512ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 2513ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallUpdateReceived(ImsCall.this); 2514ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 2515ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("callSessionUpdateReceived :: ", t); 2516ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2517ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2518ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2519ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2520ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 252171382693cbc81b1d131085f52d97879976706f55Anthony Lee public void callSessionConferenceExtended(ImsCallSession session, ImsCallSession newSession, 252271382693cbc81b1d131085f52d97879976706f55Anthony Lee ImsCallProfile profile) { 25236804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionConferenceExtended :: session=" + session + " newSession=" + 25246804851b58264d7e82b09a845118d24d36c8d831Anthony Lee newSession + ", profile=" + profile); 25256804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 252671382693cbc81b1d131085f52d97879976706f55Anthony Lee if (isTransientConferenceSession(session)) { 25276804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionConferenceExtended :: not supported for transient conference " + 2528b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee "session=" + session); 252971382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 253071382693cbc81b1d131085f52d97879976706f55Anthony Lee } 253171382693cbc81b1d131085f52d97879976706f55Anthony Lee 2532ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall newCall = createNewCall(newSession, profile); 2533ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2534ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (newCall == null) { 2535ef36ef67e009449300b0150c60c9f637e205d79eWink Saville callSessionConferenceExtendFailed(session, new ImsReasonInfo()); 2536ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return; 2537ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2538ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2539ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall.Listener listener; 2540ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2541ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(ImsCall.this) { 2542ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener = mListener; 2543ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mUpdateRequest = UPDATE_NONE; 2544ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2545ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2546ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (listener != null) { 2547ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 2548ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallConferenceExtended(ImsCall.this, newCall); 2549ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 2550ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("callSessionConferenceExtended :: ", t); 2551ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2552ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2553ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2554ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2555ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 2556ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void callSessionConferenceExtendFailed(ImsCallSession session, 2557ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo reasonInfo) { 25586804851b58264d7e82b09a845118d24d36c8d831Anthony Lee loge("callSessionConferenceExtendFailed :: reasonInfo=" + reasonInfo); 25596804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 256071382693cbc81b1d131085f52d97879976706f55Anthony Lee if (isTransientConferenceSession(session)) { 25616804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionConferenceExtendFailed :: not supported for transient " + 2562b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee "conference session=" + session); 256371382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 256471382693cbc81b1d131085f52d97879976706f55Anthony Lee } 256571382693cbc81b1d131085f52d97879976706f55Anthony Lee 2566ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall.Listener listener; 2567ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2568ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(ImsCall.this) { 2569ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener = mListener; 2570ef36ef67e009449300b0150c60c9f637e205d79eWink Saville mUpdateRequest = UPDATE_NONE; 2571ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2572ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2573ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (listener != null) { 2574ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 2575ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallConferenceExtendFailed(ImsCall.this, reasonInfo); 2576ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 2577ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("callSessionConferenceExtendFailed :: ", t); 2578ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2579ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2580ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2581ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2582ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 2583ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void callSessionConferenceExtendReceived(ImsCallSession session, 2584ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCallSession newSession, ImsCallProfile profile) { 25856804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionConferenceExtendReceived :: newSession=" + newSession + 25866804851b58264d7e82b09a845118d24d36c8d831Anthony Lee ", profile=" + profile); 25876804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 258871382693cbc81b1d131085f52d97879976706f55Anthony Lee if (isTransientConferenceSession(session)) { 25896804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionConferenceExtendReceived :: not supported for transient " + 25909bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn "conference session" + session); 259171382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 259271382693cbc81b1d131085f52d97879976706f55Anthony Lee } 259371382693cbc81b1d131085f52d97879976706f55Anthony Lee 2594ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall newCall = createNewCall(newSession, profile); 2595ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2596ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (newCall == null) { 2597ef36ef67e009449300b0150c60c9f637e205d79eWink Saville // Should all the calls be terminated...??? 2598ef36ef67e009449300b0150c60c9f637e205d79eWink Saville return; 2599ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2600ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2601ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall.Listener listener; 2602ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2603ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(ImsCall.this) { 2604ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener = mListener; 2605ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2606ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2607ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (listener != null) { 2608ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 2609ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallConferenceExtendReceived(ImsCall.this, newCall); 2610ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 2611ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("callSessionConferenceExtendReceived :: ", t); 2612ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2613ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2614ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2615ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2616ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 2617ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void callSessionInviteParticipantsRequestDelivered(ImsCallSession session) { 26186804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionInviteParticipantsRequestDelivered ::"); 26196804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 262071382693cbc81b1d131085f52d97879976706f55Anthony Lee if (isTransientConferenceSession(session)) { 26216804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionInviteParticipantsRequestDelivered :: not supported for " + 262271382693cbc81b1d131085f52d97879976706f55Anthony Lee "conference session=" + session); 262371382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 262471382693cbc81b1d131085f52d97879976706f55Anthony Lee } 262571382693cbc81b1d131085f52d97879976706f55Anthony Lee 2626ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall.Listener listener; 2627ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2628ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(ImsCall.this) { 2629ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener = mListener; 2630ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2631ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2632ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (listener != null) { 2633ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 2634ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallInviteParticipantsRequestDelivered(ImsCall.this); 2635ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 2636ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("callSessionInviteParticipantsRequestDelivered :: ", t); 2637ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2638ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2639ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2640ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2641ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 2642ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void callSessionInviteParticipantsRequestFailed(ImsCallSession session, 2643ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo reasonInfo) { 26446804851b58264d7e82b09a845118d24d36c8d831Anthony Lee loge("callSessionInviteParticipantsRequestFailed :: reasonInfo=" + reasonInfo); 26456804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 264671382693cbc81b1d131085f52d97879976706f55Anthony Lee if (isTransientConferenceSession(session)) { 26476804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionInviteParticipantsRequestFailed :: not supported for " + 264871382693cbc81b1d131085f52d97879976706f55Anthony Lee "conference session=" + session); 264971382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 265071382693cbc81b1d131085f52d97879976706f55Anthony Lee } 265171382693cbc81b1d131085f52d97879976706f55Anthony Lee 2652ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall.Listener listener; 2653ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2654ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(ImsCall.this) { 2655ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener = mListener; 2656ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2657ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2658ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (listener != null) { 2659ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 2660ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallInviteParticipantsRequestFailed(ImsCall.this, reasonInfo); 2661ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 2662ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("callSessionInviteParticipantsRequestFailed :: ", t); 2663ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2664ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2665ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2666ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2667ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 2668ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void callSessionRemoveParticipantsRequestDelivered(ImsCallSession session) { 26696804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionRemoveParticipantsRequestDelivered ::"); 26706804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 267171382693cbc81b1d131085f52d97879976706f55Anthony Lee if (isTransientConferenceSession(session)) { 26726804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionRemoveParticipantsRequestDelivered :: not supported for " + 267371382693cbc81b1d131085f52d97879976706f55Anthony Lee "conference session=" + session); 267471382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 267571382693cbc81b1d131085f52d97879976706f55Anthony Lee } 267671382693cbc81b1d131085f52d97879976706f55Anthony Lee 2677ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall.Listener listener; 2678ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2679ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(ImsCall.this) { 2680ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener = mListener; 2681ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2682ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2683ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (listener != null) { 2684ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 2685ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallRemoveParticipantsRequestDelivered(ImsCall.this); 2686ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 2687ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("callSessionRemoveParticipantsRequestDelivered :: ", t); 2688ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2689ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2690ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2691ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2692ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 2693ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void callSessionRemoveParticipantsRequestFailed(ImsCallSession session, 2694ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsReasonInfo reasonInfo) { 26956804851b58264d7e82b09a845118d24d36c8d831Anthony Lee loge("callSessionRemoveParticipantsRequestFailed :: reasonInfo=" + reasonInfo); 26966804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 269771382693cbc81b1d131085f52d97879976706f55Anthony Lee if (isTransientConferenceSession(session)) { 26986804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionRemoveParticipantsRequestFailed :: not supported for " + 26999bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn "conference session=" + session); 270071382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 270171382693cbc81b1d131085f52d97879976706f55Anthony Lee } 270271382693cbc81b1d131085f52d97879976706f55Anthony Lee 2703ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall.Listener listener; 2704ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2705ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(ImsCall.this) { 2706ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener = mListener; 2707ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2708ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2709ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (listener != null) { 2710ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 2711ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallRemoveParticipantsRequestFailed(ImsCall.this, reasonInfo); 2712ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 2713ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("callSessionRemoveParticipantsRequestFailed :: ", t); 2714ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2715ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2716ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2717ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2718ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 2719ef36ef67e009449300b0150c60c9f637e205d79eWink Saville public void callSessionConferenceStateUpdated(ImsCallSession session, 2720ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsConferenceState state) { 27216804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionConferenceStateUpdated :: state=" + state); 27226804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 2723938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn conferenceStateUpdated(state); 2724ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2725ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2726ef36ef67e009449300b0150c60c9f637e205d79eWink Saville @Override 272771382693cbc81b1d131085f52d97879976706f55Anthony Lee public void callSessionUssdMessageReceived(ImsCallSession session, int mode, 272871382693cbc81b1d131085f52d97879976706f55Anthony Lee String ussdMessage) { 27296804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionUssdMessageReceived :: mode=" + mode + ", ussdMessage=" + 27306804851b58264d7e82b09a845118d24d36c8d831Anthony Lee ussdMessage); 27316804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 273271382693cbc81b1d131085f52d97879976706f55Anthony Lee if (isTransientConferenceSession(session)) { 27336804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionUssdMessageReceived :: not supported for transient " + 2734b8799fe85b9387999f03ce7def6ace59903984a4Anthony Lee "conference session=" + session); 273571382693cbc81b1d131085f52d97879976706f55Anthony Lee return; 273671382693cbc81b1d131085f52d97879976706f55Anthony Lee } 273771382693cbc81b1d131085f52d97879976706f55Anthony Lee 2738ef36ef67e009449300b0150c60c9f637e205d79eWink Saville ImsCall.Listener listener; 2739ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2740ef36ef67e009449300b0150c60c9f637e205d79eWink Saville synchronized(ImsCall.this) { 2741ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener = mListener; 2742ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2743ef36ef67e009449300b0150c60c9f637e205d79eWink Saville 2744ef36ef67e009449300b0150c60c9f637e205d79eWink Saville if (listener != null) { 2745ef36ef67e009449300b0150c60c9f637e205d79eWink Saville try { 2746ef36ef67e009449300b0150c60c9f637e205d79eWink Saville listener.onCallUssdMessageReceived(ImsCall.this, mode, ussdMessage); 2747ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } catch (Throwable t) { 2748ef36ef67e009449300b0150c60c9f637e205d79eWink Saville loge("callSessionUssdMessageReceived :: ", t); 2749ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2750ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2751ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2752987bab859324396c0d1fc00c375f98f3f74c9067Pavel Zhamaitsiak 2753987bab859324396c0d1fc00c375f98f3f74c9067Pavel Zhamaitsiak @Override 2754987bab859324396c0d1fc00c375f98f3f74c9067Pavel Zhamaitsiak public void callSessionTtyModeReceived(ImsCallSession session, int mode) { 27556804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionTtyModeReceived :: mode=" + mode); 2756987bab859324396c0d1fc00c375f98f3f74c9067Pavel Zhamaitsiak 2757a6cae36b881e26fa288a83c94b8c357fd436140ePavel Zhamaitsiak ImsCall.Listener listener; 2758a6cae36b881e26fa288a83c94b8c357fd436140ePavel Zhamaitsiak 2759a6cae36b881e26fa288a83c94b8c357fd436140ePavel Zhamaitsiak synchronized(ImsCall.this) { 2760a6cae36b881e26fa288a83c94b8c357fd436140ePavel Zhamaitsiak listener = mListener; 2761a6cae36b881e26fa288a83c94b8c357fd436140ePavel Zhamaitsiak } 2762a6cae36b881e26fa288a83c94b8c357fd436140ePavel Zhamaitsiak 2763a6cae36b881e26fa288a83c94b8c357fd436140ePavel Zhamaitsiak if (listener != null) { 2764a6cae36b881e26fa288a83c94b8c357fd436140ePavel Zhamaitsiak try { 2765a6cae36b881e26fa288a83c94b8c357fd436140ePavel Zhamaitsiak listener.onCallSessionTtyModeReceived(ImsCall.this, mode); 2766a6cae36b881e26fa288a83c94b8c357fd436140ePavel Zhamaitsiak } catch (Throwable t) { 2767a6cae36b881e26fa288a83c94b8c357fd436140ePavel Zhamaitsiak loge("callSessionTtyModeReceived :: ", t); 2768987bab859324396c0d1fc00c375f98f3f74c9067Pavel Zhamaitsiak } 2769987bab859324396c0d1fc00c375f98f3f74c9067Pavel Zhamaitsiak } 2770987bab859324396c0d1fc00c375f98f3f74c9067Pavel Zhamaitsiak } 27711463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar 277225394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn /** 277325394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * Notifies of a change to the multiparty state for this {@code ImsCallSession}. 277425394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * 277525394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * @param session The call session. 277625394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * @param isMultiParty {@code true} if the session became multiparty, {@code false} 277725394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn * otherwise. 277825394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn */ 277925394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn @Override 278025394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn public void callSessionMultipartyStateChanged(ImsCallSession session, 278125394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn boolean isMultiParty) { 278225394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn if (VDBG) { 2783691a1cc831e1bade18cb39f917f9aebbb5939ab8Pavel Zhamaitsiak logi("callSessionMultipartyStateChanged isMultiParty: " + (isMultiParty ? "Y" 278425394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn : "N")); 278525394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn } 278625394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn 278725394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn ImsCall.Listener listener; 278825394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn 278925394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn synchronized(ImsCall.this) { 279025394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn listener = mListener; 279125394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn } 279225394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn 279325394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn if (listener != null) { 279425394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn try { 279525394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn listener.onMultipartyStateChanged(ImsCall.this, isMultiParty); 279625394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn } catch (Throwable t) { 279725394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn loge("callSessionMultipartyStateChanged :: ", t); 279825394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn } 279925394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn } 280025394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn } 280125394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn 28021463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar public void callSessionHandover(ImsCallSession session, int srcAccessTech, 28031463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar int targetAccessTech, ImsReasonInfo reasonInfo) { 28046804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("callSessionHandover :: session=" + session + ", srcAccessTech=" + 28056804851b58264d7e82b09a845118d24d36c8d831Anthony Lee srcAccessTech + ", targetAccessTech=" + targetAccessTech + ", reasonInfo=" + 28066804851b58264d7e82b09a845118d24d36c8d831Anthony Lee reasonInfo); 28071463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar 28081463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar ImsCall.Listener listener; 28091463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar 28101463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar synchronized(ImsCall.this) { 28111463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar listener = mListener; 28121463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar } 28131463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar 28141463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar if (listener != null) { 28151463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar try { 28161463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar listener.onCallHandover(ImsCall.this, srcAccessTech, targetAccessTech, 28171463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar reasonInfo); 28181463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar } catch (Throwable t) { 28191463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar loge("callSessionHandover :: ", t); 28201463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar } 28211463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar } 28221463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar } 28231463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar 28241463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar @Override 28251463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar public void callSessionHandoverFailed(ImsCallSession session, int srcAccessTech, 28261463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar int targetAccessTech, ImsReasonInfo reasonInfo) { 28276804851b58264d7e82b09a845118d24d36c8d831Anthony Lee loge("callSessionHandoverFailed :: session=" + session + ", srcAccessTech=" + 28286804851b58264d7e82b09a845118d24d36c8d831Anthony Lee srcAccessTech + ", targetAccessTech=" + targetAccessTech + ", reasonInfo=" + 28296804851b58264d7e82b09a845118d24d36c8d831Anthony Lee reasonInfo); 28301463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar 28311463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar ImsCall.Listener listener; 28321463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar 28331463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar synchronized(ImsCall.this) { 28341463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar listener = mListener; 28351463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar } 28361463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar 28371463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar if (listener != null) { 28381463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar try { 28391463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar listener.onCallHandoverFailed(ImsCall.this, srcAccessTech, targetAccessTech, 28401463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar reasonInfo); 28411463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar } catch (Throwable t) { 28421463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar loge("callSessionHandoverFailed :: ", t); 28431463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar } 28441463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar } 28451463174fa4bab35f04dfa71196c277dfeb603717Rekha Kumar } 2846d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh 2847d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh @Override 2848d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh public void callSessionSuppServiceReceived(ImsCallSession session, 2849d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh ImsSuppServiceNotification suppServiceInfo ) { 2850d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh if (isTransientConferenceSession(session)) { 2851d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh logi("callSessionSuppServiceReceived :: not supported for transient conference" 2852d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh + " session=" + session); 2853d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh return; 2854d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh } 2855d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh 2856d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh logi("callSessionSuppServiceReceived :: session=" + session + 2857d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh ", suppServiceInfo" + suppServiceInfo); 2858d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh 2859d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh ImsCall.Listener listener; 2860d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh 2861d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh synchronized(ImsCall.this) { 2862d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh listener = mListener; 2863d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh } 2864d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh 2865d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh if (listener != null) { 2866d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh try { 2867d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh listener.onCallSuppServiceReceived(ImsCall.this, suppServiceInfo); 2868d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh } catch (Throwable t) { 2869d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh loge("callSessionSuppServiceReceived :: ", t); 2870d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh } 2871d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh } 2872d3adfadd868b19e2423674bfefa5ba778f743bf2Shriram Ganesh } 2873ef36ef67e009449300b0150c60c9f637e205d79eWink Saville } 2874938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn 2875938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn /** 2876938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn * Report a new conference state to the current {@link ImsCall} and inform listeners of the 2877938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn * change. Marked as {@code VisibleForTesting} so that the 2878938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn * {@code com.android.internal.telephony.TelephonyTester} class can inject a test conference 2879938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn * event package into a regular ongoing IMS call. 2880938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn * 2881938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn * @param state The {@link ImsConferenceState}. 2882938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn */ 2883938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn @VisibleForTesting 2884938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn public void conferenceStateUpdated(ImsConferenceState state) { 2885938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn Listener listener; 2886938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn 2887938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn synchronized(this) { 2888938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn notifyConferenceStateUpdated(state); 2889938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn listener = mListener; 2890938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn } 2891938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn 2892938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn if (listener != null) { 2893938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn try { 2894938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn listener.onCallConferenceStateUpdated(this, state); 2895938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn } catch (Throwable t) { 2896938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn loge("callSessionConferenceStateUpdated :: ", t); 2897938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn } 2898938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn } 2899938116f08e88772f6736ddd7aa7541c204538b66Tyler Gunn } 2900168c634eef29f21c73129164207d04b8cce23738Tyler Gunn 2901168c634eef29f21c73129164207d04b8cce23738Tyler Gunn /** 2902168c634eef29f21c73129164207d04b8cce23738Tyler Gunn * Provides a human-readable string representation of an update request. 2903168c634eef29f21c73129164207d04b8cce23738Tyler Gunn * 2904168c634eef29f21c73129164207d04b8cce23738Tyler Gunn * @param updateRequest The update request. 2905168c634eef29f21c73129164207d04b8cce23738Tyler Gunn * @return The string representation. 2906168c634eef29f21c73129164207d04b8cce23738Tyler Gunn */ 2907168c634eef29f21c73129164207d04b8cce23738Tyler Gunn private String updateRequestToString(int updateRequest) { 2908168c634eef29f21c73129164207d04b8cce23738Tyler Gunn switch (updateRequest) { 2909168c634eef29f21c73129164207d04b8cce23738Tyler Gunn case UPDATE_NONE: 2910168c634eef29f21c73129164207d04b8cce23738Tyler Gunn return "NONE"; 2911168c634eef29f21c73129164207d04b8cce23738Tyler Gunn case UPDATE_HOLD: 2912168c634eef29f21c73129164207d04b8cce23738Tyler Gunn return "HOLD"; 2913168c634eef29f21c73129164207d04b8cce23738Tyler Gunn case UPDATE_HOLD_MERGE: 2914168c634eef29f21c73129164207d04b8cce23738Tyler Gunn return "HOLD_MERGE"; 2915168c634eef29f21c73129164207d04b8cce23738Tyler Gunn case UPDATE_RESUME: 2916168c634eef29f21c73129164207d04b8cce23738Tyler Gunn return "RESUME"; 2917168c634eef29f21c73129164207d04b8cce23738Tyler Gunn case UPDATE_MERGE: 2918168c634eef29f21c73129164207d04b8cce23738Tyler Gunn return "MERGE"; 2919168c634eef29f21c73129164207d04b8cce23738Tyler Gunn case UPDATE_EXTEND_TO_CONFERENCE: 2920168c634eef29f21c73129164207d04b8cce23738Tyler Gunn return "EXTEND_TO_CONFERENCE"; 2921168c634eef29f21c73129164207d04b8cce23738Tyler Gunn case UPDATE_UNSPECIFIED: 2922168c634eef29f21c73129164207d04b8cce23738Tyler Gunn return "UNSPECIFIED"; 2923168c634eef29f21c73129164207d04b8cce23738Tyler Gunn default: 2924168c634eef29f21c73129164207d04b8cce23738Tyler Gunn return "UNKNOWN"; 2925168c634eef29f21c73129164207d04b8cce23738Tyler Gunn } 2926168c634eef29f21c73129164207d04b8cce23738Tyler Gunn } 2927168c634eef29f21c73129164207d04b8cce23738Tyler Gunn 2928168c634eef29f21c73129164207d04b8cce23738Tyler Gunn /** 29299bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * Clears the merge peer for this call, ensuring that the peer's connection to this call is also 29309bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * severed at the same time. 29319bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn */ 2932c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee private void clearMergeInfo() { 29336804851b58264d7e82b09a845118d24d36c8d831Anthony Lee if (CONF_DBG) { 29346804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("clearMergeInfo :: clearing all merge info"); 2935c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } 2936047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn 2937c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // First clear out the merge partner then clear ourselves out. 29389bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn if (mMergeHost != null) { 29399bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn mMergeHost.mMergePeer = null; 2940165aed55d289ae2a5cdf34de4164c2395f46b8c1Libin.Tang@motorola.com mMergeHost.mUpdateRequest = UPDATE_NONE; 2941c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee mMergeHost.mCallSessionMergePending = false; 29429bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn } 29439bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn if (mMergePeer != null) { 29449bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn mMergePeer.mMergeHost = null; 2945165aed55d289ae2a5cdf34de4164c2395f46b8c1Libin.Tang@motorola.com mMergePeer.mUpdateRequest = UPDATE_NONE; 2946c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee mMergePeer.mCallSessionMergePending = false; 29479bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn } 2948c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee mMergeHost = null; 2949c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee mMergePeer = null; 2950c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee mUpdateRequest = UPDATE_NONE; 2951c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee mCallSessionMergePending = false; 29529bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn } 29539bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn 29549bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn /** 29559bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * Sets the merge peer for the current call. The merge peer is the background call that will be 29569bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * merged into this call. On the merge peer, sets the merge host to be this call. 29579bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * 29589bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * @param mergePeer The peer call to be merged into this one. 29599bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn */ 29609bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn private void setMergePeer(ImsCall mergePeer) { 29619bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn mMergePeer = mergePeer; 29629bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn mMergeHost = null; 29639bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn 29649bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn mergePeer.mMergeHost = ImsCall.this; 29659bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn mergePeer.mMergePeer = null; 29669bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn } 29679bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn 29689bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn /** 29699bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * Sets the merge hody for the current call. The merge host is the foreground call this call 29709bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * will be merged into. On the merge host, sets the merge peer to be this call. 29719bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * 29729bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * @param mergeHost The merge host this call will be merged into. 29739bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn */ 29749bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn public void setMergeHost(ImsCall mergeHost) { 29759bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn mMergeHost = mergeHost; 29769bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn mMergePeer = null; 29779bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn 29789bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn mergeHost.mMergeHost = null; 29799bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn mergeHost.mMergePeer = ImsCall.this; 29809bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn } 29819bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn 29829bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn /** 29839bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * Determines if the current call is in the process of merging with another call or conference. 29849bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * 29859bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * @return {@code true} if in the process of merging. 29869bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn */ 29879bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn private boolean isMerging() { 29889bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn return mMergePeer != null || mMergeHost != null; 29899bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn } 29909bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn 29919bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn /** 29929bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * Determines if the current call is the host of the merge. 29939bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * 29949bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * @return {@code true} if the call is the merge host. 29959bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn */ 29969bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn private boolean isMergeHost() { 29979bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn return mMergePeer != null && mMergeHost == null; 29989bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn } 29999bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn 30009bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn /** 30019bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * Determines if the current call is the peer of the merge. 30029bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * 30039bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn * @return {@code true} if the call is the merge peer. 30049bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn */ 30059bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn private boolean isMergePeer() { 30069bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn return mMergePeer == null && mMergeHost != null; 30079bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn } 30089bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn 30099bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn /** 3010047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn * Determines if the call session is pending merge into a conference or not. 3011047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn * 3012047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn * @return {@code true} if a merge into a conference is pending, {@code false} otherwise. 3013047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn */ 3014047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn private boolean isCallSessionMergePending() { 3015047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn return mCallSessionMergePending; 3016047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn } 3017047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn 3018047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn /** 3019047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn * Sets flag indicating whether the call session is pending merge into a conference or not. 3020047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn * 3021047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn * @param callSessionMergePending {@code true} if a merge into the conference is pending, 3022047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn * {@code false} otherwise. 3023047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn */ 3024047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn private void setCallSessionMergePending(boolean callSessionMergePending) { 3025047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn mCallSessionMergePending = callSessionMergePending; 3026047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn } 3027047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn 3028047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn /** 3029047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn * Determines if there is a conference merge in process. If there is a merge in process, 3030047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn * determines if both the merge host and peer sessions have completed the merge process. This 3031047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn * means that we have received terminate or hold signals for the sessions, indicating that they 3032047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn * are no longer in the process of being merged into the conference. 3033047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn * <p> 3034c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee * The sessions are considered to have merged if: both calls still have merge peer/host 3035c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee * relationships configured, both sessions are not waiting to be merged into the conference, 3036c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee * and the transient conference session is alive in the case of an initial conference. 3037047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn * 3038047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn * @return {@code true} where the host and peer sessions have finished merging into the 3039047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn * conference, {@code false} if the merge has not yet completed, and {@code false} if there 3040047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn * is no conference merge in progress. 3041047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn */ 3042c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee private boolean shouldProcessConferenceResult() { 3043c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee boolean areMergeTriggersDone = false; 3044c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee 3045c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee synchronized (ImsCall.this) { 3046c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // if there is a merge going on, then the merge host/peer relationships should have been 3047c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // set up. This works for both the initial conference or merging a call into an 3048c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // existing conference. 3049c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee if (!isMergeHost() && !isMergePeer()) { 30506804851b58264d7e82b09a845118d24d36c8d831Anthony Lee if (CONF_DBG) { 30516804851b58264d7e82b09a845118d24d36c8d831Anthony Lee loge("shouldProcessConferenceResult :: no merge in progress"); 3052c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } 3053c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee return false; 3054c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } 3055047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn 3056c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // There is a merge in progress, so check the sessions to ensure: 3057c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // 1. Both calls have completed being merged (or failing to merge) into the conference. 3058c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // 2. The transient conference session is alive. 3059c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee if (isMergeHost()) { 30606804851b58264d7e82b09a845118d24d36c8d831Anthony Lee if (CONF_DBG) { 30616804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("shouldProcessConferenceResult :: We are a merge host"); 30626804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("shouldProcessConferenceResult :: Here is the merge peer=" + mMergePeer); 3063c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } 3064c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee areMergeTriggersDone = !isCallSessionMergePending() && 3065c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee !mMergePeer.isCallSessionMergePending(); 3066c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee if (!isMultiparty()) { 3067c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // Only check the transient session when there is no existing conference 3068c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee areMergeTriggersDone &= isSessionAlive(mTransientConferenceSession); 3069c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } 3070c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } else if (isMergePeer()) { 30716804851b58264d7e82b09a845118d24d36c8d831Anthony Lee if (CONF_DBG) { 30726804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("shouldProcessConferenceResult :: We are a merge peer"); 30736804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("shouldProcessConferenceResult :: Here is the merge host=" + mMergeHost); 3074c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } 3075c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee areMergeTriggersDone = !isCallSessionMergePending() && 3076c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee !mMergeHost.isCallSessionMergePending(); 3077c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee if (!mMergeHost.isMultiparty()) { 3078c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // Only check the transient session when there is no existing conference 3079c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee areMergeTriggersDone &= isSessionAlive(mMergeHost.mTransientConferenceSession); 3080c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } else { 3081c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // This else block is a special case for Verizon to handle these steps 3082c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // 1. Establish a conference call. 3083c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // 2. Add a new call (conference in in BG) 3084c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // 3. Swap (conference active on FG) 3085c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // 4. Merge 3086c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // What happens here is that the BG call gets a terminated callback 3087c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // because it was added to the conference. I've seen where 3088c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // the FG gets no callback at all because its already active. 3089c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // So if we continue to wait for it to set its isCallSessionMerging 3090c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // flag to false...we'll be waiting forever. 3091c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee areMergeTriggersDone = !isCallSessionMergePending(); 3092c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } 3093c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } else { 3094c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee // Realistically this shouldn't happen, but best to be safe. 3095c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee loge("shouldProcessConferenceResult : merge in progress but call is neither" + 30966804851b58264d7e82b09a845118d24d36c8d831Anthony Lee " host nor peer."); 3097c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } 30986804851b58264d7e82b09a845118d24d36c8d831Anthony Lee if (CONF_DBG) { 30996804851b58264d7e82b09a845118d24d36c8d831Anthony Lee logi("shouldProcessConferenceResult :: returning:" + 3100c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee (areMergeTriggersDone ? "true" : "false")); 3101c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee } 3102047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn } 3103c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee return areMergeTriggersDone; 3104047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn } 3105047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn 3106047d8101113030f34f89f7c9ba015d6c5c3abba6Tyler Gunn /** 3107168c634eef29f21c73129164207d04b8cce23738Tyler Gunn * Provides a string representation of the {@link ImsCall}. Primarily intended for use in log 3108168c634eef29f21c73129164207d04b8cce23738Tyler Gunn * statements. 3109168c634eef29f21c73129164207d04b8cce23738Tyler Gunn * 3110168c634eef29f21c73129164207d04b8cce23738Tyler Gunn * @return String representation of call. 3111168c634eef29f21c73129164207d04b8cce23738Tyler Gunn */ 3112168c634eef29f21c73129164207d04b8cce23738Tyler Gunn @Override 3113168c634eef29f21c73129164207d04b8cce23738Tyler Gunn public String toString() { 3114168c634eef29f21c73129164207d04b8cce23738Tyler Gunn StringBuilder sb = new StringBuilder(); 3115168c634eef29f21c73129164207d04b8cce23738Tyler Gunn sb.append("[ImsCall objId:"); 3116168c634eef29f21c73129164207d04b8cce23738Tyler Gunn sb.append(System.identityHashCode(this)); 31179bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn sb.append(" onHold:"); 31189bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn sb.append(isOnHold() ? "Y" : "N"); 31199bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn sb.append(" mute:"); 31209bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn sb.append(isMuted() ? "Y" : "N"); 312150b03e9261c7717817ebfb8e4086f949d0ad9c18Pavel Zhamaitsiak if (mCallProfile != null) { 312250b03e9261c7717817ebfb8e4086f949d0ad9c18Pavel Zhamaitsiak sb.append(" tech:"); 312350b03e9261c7717817ebfb8e4086f949d0ad9c18Pavel Zhamaitsiak sb.append(mCallProfile.getCallExtra(ImsCallProfile.EXTRA_CALL_RAT_TYPE)); 312450b03e9261c7717817ebfb8e4086f949d0ad9c18Pavel Zhamaitsiak } 31259bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn sb.append(" updateRequest:"); 31269bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn sb.append(updateRequestToString(mUpdateRequest)); 312787466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn sb.append(" merging:"); 312887466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn sb.append(isMerging() ? "Y" : "N"); 312987466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn if (isMerging()) { 313087466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn if (isMergePeer()) { 313187466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn sb.append("P"); 313287466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn } else { 313387466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn sb.append("H"); 313487466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn } 313587466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn } 3136c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee sb.append(" merge action pending:"); 3137c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee sb.append(isCallSessionMergePending() ? "Y" : "N"); 313887466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn sb.append(" merged:"); 313987466c59b1980ec4e56bb17fae8b855efcc17fd8Tyler Gunn sb.append(isMerged() ? "Y" : "N"); 3140168c634eef29f21c73129164207d04b8cce23738Tyler Gunn sb.append(" multiParty:"); 31419bd5ca59239ac4acdccf97c0ab7a2a4ab957bf28Tyler Gunn sb.append(isMultiparty() ? "Y" : "N"); 314225394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn sb.append(" confHost:"); 314325394099999f724f7806cbc7119ecca3708cf3b3Tyler Gunn sb.append(isConferenceHost() ? "Y" : "N"); 3144c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee sb.append(" buried term:"); 3145c479f66e3d1f3cfdd3e88a050881f7cd663a5a90Anthony Lee sb.append(mSessionEndDuringMerge ? "Y" : "N"); 3146168c634eef29f21c73129164207d04b8cce23738Tyler Gunn sb.append(" session:"); 3147168c634eef29f21c73129164207d04b8cce23738Tyler Gunn sb.append(mSession); 3148168c634eef29f21c73129164207d04b8cce23738Tyler Gunn sb.append(" transientSession:"); 3149168c634eef29f21c73129164207d04b8cce23738Tyler Gunn sb.append(mTransientConferenceSession); 3150168c634eef29f21c73129164207d04b8cce23738Tyler Gunn sb.append("]"); 3151168c634eef29f21c73129164207d04b8cce23738Tyler Gunn return sb.toString(); 3152168c634eef29f21c73129164207d04b8cce23738Tyler Gunn } 31536804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 31546804851b58264d7e82b09a845118d24d36c8d831Anthony Lee private void throwImsException(Throwable t, int code) throws ImsException { 31556804851b58264d7e82b09a845118d24d36c8d831Anthony Lee if (t instanceof ImsException) { 31566804851b58264d7e82b09a845118d24d36c8d831Anthony Lee throw (ImsException) t; 31576804851b58264d7e82b09a845118d24d36c8d831Anthony Lee } else { 31586804851b58264d7e82b09a845118d24d36c8d831Anthony Lee throw new ImsException(String.valueOf(code), t, code); 31596804851b58264d7e82b09a845118d24d36c8d831Anthony Lee } 31606804851b58264d7e82b09a845118d24d36c8d831Anthony Lee } 31616804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 31626804851b58264d7e82b09a845118d24d36c8d831Anthony Lee /** 31636804851b58264d7e82b09a845118d24d36c8d831Anthony Lee * Append the ImsCall information to the provided string. Usefull for as a logging helper. 31646804851b58264d7e82b09a845118d24d36c8d831Anthony Lee * @param s The original string 31656804851b58264d7e82b09a845118d24d36c8d831Anthony Lee * @return The original string with {@code ImsCall} information appended to it. 31666804851b58264d7e82b09a845118d24d36c8d831Anthony Lee */ 31676804851b58264d7e82b09a845118d24d36c8d831Anthony Lee private String appendImsCallInfoToString(String s) { 31686804851b58264d7e82b09a845118d24d36c8d831Anthony Lee StringBuilder sb = new StringBuilder(); 31696804851b58264d7e82b09a845118d24d36c8d831Anthony Lee sb.append(s); 31706804851b58264d7e82b09a845118d24d36c8d831Anthony Lee sb.append(" ImsCall="); 31716804851b58264d7e82b09a845118d24d36c8d831Anthony Lee sb.append(ImsCall.this); 31726804851b58264d7e82b09a845118d24d36c8d831Anthony Lee return sb.toString(); 31736804851b58264d7e82b09a845118d24d36c8d831Anthony Lee } 31746804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 31756804851b58264d7e82b09a845118d24d36c8d831Anthony Lee /** 31766804851b58264d7e82b09a845118d24d36c8d831Anthony Lee * Log a string to the radio buffer at the info level. 31776804851b58264d7e82b09a845118d24d36c8d831Anthony Lee * @param s The message to log 31786804851b58264d7e82b09a845118d24d36c8d831Anthony Lee */ 31796804851b58264d7e82b09a845118d24d36c8d831Anthony Lee private void logi(String s) { 31806804851b58264d7e82b09a845118d24d36c8d831Anthony Lee Log.i(TAG, appendImsCallInfoToString(s)); 31816804851b58264d7e82b09a845118d24d36c8d831Anthony Lee } 31826804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 31836804851b58264d7e82b09a845118d24d36c8d831Anthony Lee /** 31846804851b58264d7e82b09a845118d24d36c8d831Anthony Lee * Log a string to the radio buffer at the debug level. 31856804851b58264d7e82b09a845118d24d36c8d831Anthony Lee * @param s The message to log 31866804851b58264d7e82b09a845118d24d36c8d831Anthony Lee */ 31876804851b58264d7e82b09a845118d24d36c8d831Anthony Lee private void logd(String s) { 31886804851b58264d7e82b09a845118d24d36c8d831Anthony Lee Log.d(TAG, appendImsCallInfoToString(s)); 31896804851b58264d7e82b09a845118d24d36c8d831Anthony Lee } 31906804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 31916804851b58264d7e82b09a845118d24d36c8d831Anthony Lee /** 31926804851b58264d7e82b09a845118d24d36c8d831Anthony Lee * Log a string to the radio buffer at the verbose level. 31936804851b58264d7e82b09a845118d24d36c8d831Anthony Lee * @param s The message to log 31946804851b58264d7e82b09a845118d24d36c8d831Anthony Lee */ 31956804851b58264d7e82b09a845118d24d36c8d831Anthony Lee private void logv(String s) { 31966804851b58264d7e82b09a845118d24d36c8d831Anthony Lee Log.v(TAG, appendImsCallInfoToString(s)); 31976804851b58264d7e82b09a845118d24d36c8d831Anthony Lee } 31986804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 31996804851b58264d7e82b09a845118d24d36c8d831Anthony Lee /** 32006804851b58264d7e82b09a845118d24d36c8d831Anthony Lee * Log a string to the radio buffer at the error level. 32016804851b58264d7e82b09a845118d24d36c8d831Anthony Lee * @param s The message to log 32026804851b58264d7e82b09a845118d24d36c8d831Anthony Lee */ 32036804851b58264d7e82b09a845118d24d36c8d831Anthony Lee private void loge(String s) { 32046804851b58264d7e82b09a845118d24d36c8d831Anthony Lee Log.e(TAG, appendImsCallInfoToString(s)); 32056804851b58264d7e82b09a845118d24d36c8d831Anthony Lee } 32066804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 32076804851b58264d7e82b09a845118d24d36c8d831Anthony Lee /** 32086804851b58264d7e82b09a845118d24d36c8d831Anthony Lee * Log a string to the radio buffer at the error level with a throwable 32096804851b58264d7e82b09a845118d24d36c8d831Anthony Lee * @param s The message to log 32106804851b58264d7e82b09a845118d24d36c8d831Anthony Lee * @param t The associated throwable 32116804851b58264d7e82b09a845118d24d36c8d831Anthony Lee */ 32126804851b58264d7e82b09a845118d24d36c8d831Anthony Lee private void loge(String s, Throwable t) { 32136804851b58264d7e82b09a845118d24d36c8d831Anthony Lee Log.e(TAG, appendImsCallInfoToString(s), t); 32146804851b58264d7e82b09a845118d24d36c8d831Anthony Lee } 32156804851b58264d7e82b09a845118d24d36c8d831Anthony Lee 3216ef36ef67e009449300b0150c60c9f637e205d79eWink Saville} 3217