/*
 * Copyright (c) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.ims.internal;

import android.os.Message;
import android.os.RemoteException;

import java.util.Objects;

import android.telephony.ims.stub.ImsCallSessionListenerImplBase;
import android.util.Log;
import com.android.ims.ImsCallProfile;
import com.android.ims.ImsConferenceState;
import com.android.ims.ImsReasonInfo;
import com.android.ims.ImsStreamMediaProfile;
import com.android.ims.ImsSuppServiceNotification;

/**
 * Provides the call initiation/termination, and media exchange between two IMS endpoints.
 * It directly communicates with IMS service which implements the IMS protocol behavior.
 *
 * @hide
 */
public class ImsCallSession {
    private static final String TAG = "ImsCallSession";

    /**
     * Defines IMS call session state.
     */
    public static class State {
        public static final int IDLE = 0;
        public static final int INITIATED = 1;
        public static final int NEGOTIATING = 2;
        public static final int ESTABLISHING = 3;
        public static final int ESTABLISHED = 4;

        public static final int RENEGOTIATING = 5;
        public static final int REESTABLISHING = 6;

        public static final int TERMINATING = 7;
        public static final int TERMINATED = 8;

        public static final int INVALID = (-1);

        /**
         * Converts the state to string.
         */
        public static String toString(int state) {
            switch (state) {
                case IDLE:
                    return "IDLE";
                case INITIATED:
                    return "INITIATED";
                case NEGOTIATING:
                    return "NEGOTIATING";
                case ESTABLISHING:
                    return "ESTABLISHING";
                case ESTABLISHED:
                    return "ESTABLISHED";
                case RENEGOTIATING:
                    return "RENEGOTIATING";
                case REESTABLISHING:
                    return "REESTABLISHING";
                case TERMINATING:
                    return "TERMINATING";
                case TERMINATED:
                    return "TERMINATED";
                default:
                    return "UNKNOWN";
            }
        }

        private State() {
        }
    }

    /**
     * Listener for events relating to an IMS session, such as when a session is being
     * recieved ("on ringing") or a call is outgoing ("on calling").
     * <p>Many of these events are also received by {@link ImsCall.Listener}.</p>
     */
    public static class Listener {
        /**
         * Called when a request is sent out to initiate a new session
         * and 1xx response is received from the network.
         *
         * @param session the session object that carries out the IMS session
         */
        public void callSessionProgressing(ImsCallSession session,
                ImsStreamMediaProfile profile) {
            // no-op
        }

        /**
         * Called when the session is established.
         *
         * @param session the session object that carries out the IMS session
         */
        public void callSessionStarted(ImsCallSession session,
                ImsCallProfile profile) {
            // no-op
        }

        /**
         * Called when the session establishment is failed.
         *
         * @param session the session object that carries out the IMS session
         * @param reasonInfo detailed reason of the session establishment failure
         */
        public void callSessionStartFailed(ImsCallSession session,
                ImsReasonInfo reasonInfo) {
        }

        /**
         * Called when the session is terminated.
         *
         * @param session the session object that carries out the IMS session
         * @param reasonInfo detailed reason of the session termination
         */
        public void callSessionTerminated(ImsCallSession session,
                ImsReasonInfo reasonInfo) {
        }

        /**
         * Called when the session is in hold.
         *
         * @param session the session object that carries out the IMS session
         */
        public void callSessionHeld(ImsCallSession session,
                ImsCallProfile profile) {
        }

        /**
         * Called when the session hold is failed.
         *
         * @param session the session object that carries out the IMS session
         * @param reasonInfo detailed reason of the session hold failure
         */
        public void callSessionHoldFailed(ImsCallSession session,
                ImsReasonInfo reasonInfo) {
        }

        /**
         * Called when the session hold is received from the remote user.
         *
         * @param session the session object that carries out the IMS session
         */
        public void callSessionHoldReceived(ImsCallSession session,
                ImsCallProfile profile) {
        }

        /**
         * Called when the session resume is done.
         *
         * @param session the session object that carries out the IMS session
         */
        public void callSessionResumed(ImsCallSession session,
                ImsCallProfile profile) {
        }

        /**
         * Called when the session resume is failed.
         *
         * @param session the session object that carries out the IMS session
         * @param reasonInfo detailed reason of the session resume failure
         */
        public void callSessionResumeFailed(ImsCallSession session,
                ImsReasonInfo reasonInfo) {
        }

        /**
         * Called when the session resume is received from the remote user.
         *
         * @param session the session object that carries out the IMS session
         */
        public void callSessionResumeReceived(ImsCallSession session,
                ImsCallProfile profile) {
        }

        /**
         * Called when the session merge has been started.  At this point, the {@code newSession}
         * represents the session which has been initiated to the IMS conference server for the
         * new merged conference.
         *
         * @param session the session object that carries out the IMS session
         * @param newSession the session object that is merged with an active & hold session
         */
        public void callSessionMergeStarted(ImsCallSession session,
                ImsCallSession newSession, ImsCallProfile profile) {
        }

        /**
         * Called when the session merge is successful and the merged session is active.
         *
         * @param session the session object that carries out the IMS session
         */
        public void callSessionMergeComplete(ImsCallSession session) {
        }

        /**
         * Called when the session merge has failed.
         *
         * @param session the session object that carries out the IMS session
         * @param reasonInfo detailed reason of the call merge failure
         */
        public void callSessionMergeFailed(ImsCallSession session,
                ImsReasonInfo reasonInfo) {
        }

        /**
         * Called when the session is updated (except for hold/unhold).
         *
         * @param session the session object that carries out the IMS session
         */
        public void callSessionUpdated(ImsCallSession session,
                ImsCallProfile profile) {
        }

        /**
         * Called when the session update is failed.
         *
         * @param session the session object that carries out the IMS session
         * @param reasonInfo detailed reason of the session update failure
         */
        public void callSessionUpdateFailed(ImsCallSession session,
                ImsReasonInfo reasonInfo) {
        }

        /**
         * Called when the session update is received from the remote user.
         *
         * @param session the session object that carries out the IMS session
         */
        public void callSessionUpdateReceived(ImsCallSession session,
                ImsCallProfile profile) {
            // no-op
        }

        /**
         * Called when the session is extended to the conference session.
         *
         * @param session the session object that carries out the IMS session
         * @param newSession the session object that is extended to the conference
         *      from the active session
         */
        public void callSessionConferenceExtended(ImsCallSession session,
                ImsCallSession newSession, ImsCallProfile profile) {
        }

        /**
         * Called when the conference extension is failed.
         *
         * @param session the session object that carries out the IMS session
         * @param reasonInfo detailed reason of the conference extension failure
         */
        public void callSessionConferenceExtendFailed(ImsCallSession session,
                ImsReasonInfo reasonInfo) {
        }

        /**
         * Called when the conference extension is received from the remote user.
         *
         * @param session the session object that carries out the IMS session
         */
        public void callSessionConferenceExtendReceived(ImsCallSession session,
                ImsCallSession newSession, ImsCallProfile profile) {
            // no-op
        }

        /**
         * Called when the invitation request of the participants is delivered to the conference
         * server.
         *
         * @param session the session object that carries out the IMS session
         */
        public void callSessionInviteParticipantsRequestDelivered(ImsCallSession session) {
            // no-op
        }

        /**
         * Called when the invitation request of the participants is failed.
         *
         * @param session the session object that carries out the IMS session
         * @param reasonInfo detailed reason of the conference invitation failure
         */
        public void callSessionInviteParticipantsRequestFailed(ImsCallSession session,
                ImsReasonInfo reasonInfo) {
            // no-op
        }

        /**
         * Called when the removal request of the participants is delivered to the conference
         * server.
         *
         * @param session the session object that carries out the IMS session
         */
        public void callSessionRemoveParticipantsRequestDelivered(ImsCallSession session) {
            // no-op
        }

        /**
         * Called when the removal request of the participants is failed.
         *
         * @param session the session object that carries out the IMS session
         * @param reasonInfo detailed reason of the conference removal failure
         */
        public void callSessionRemoveParticipantsRequestFailed(ImsCallSession session,
                ImsReasonInfo reasonInfo) {
            // no-op
        }

        /**
         * Called when the conference state is updated.
         *
         * @param session the session object that carries out the IMS session
         */
        public void callSessionConferenceStateUpdated(ImsCallSession session,
                ImsConferenceState state) {
            // no-op
        }

        /**
         * Called when the USSD message is received from the network.
         *
         * @param mode mode of the USSD message (REQUEST / NOTIFY)
         * @param ussdMessage USSD message
         */
        public void callSessionUssdMessageReceived(ImsCallSession session,
                int mode, String ussdMessage) {
            // no-op
        }

        /**
         * Called when session access technology changes
         *
         * @param session IMS session object
         * @param srcAccessTech original access technology
         * @param targetAccessTech new access technology
         * @param reasonInfo
         */
        public void callSessionHandover(ImsCallSession session,
                                 int srcAccessTech, int targetAccessTech,
                                 ImsReasonInfo reasonInfo) {
            // no-op
        }

        /**
         * Called when session access technology change fails
         *
         * @param session IMS session object
         * @param srcAccessTech original access technology
         * @param targetAccessTech new access technology
         * @param reasonInfo handover failure reason
         */
        public void callSessionHandoverFailed(ImsCallSession session,
                                       int srcAccessTech, int targetAccessTech,
                                       ImsReasonInfo reasonInfo) {
            // no-op
        }

        /**
         * Called when TTY mode of remote party changed
         *
         * @param session IMS session object
         * @param mode TTY mode of remote party
         */
        public void callSessionTtyModeReceived(ImsCallSession session,
                                       int mode) {
            // no-op
        }

        /**
         * Notifies of a change to the multiparty state for this {@code ImsCallSession}.
         *
         * @param session The call session.
         * @param isMultiParty {@code true} if the session became multiparty, {@code false}
         *      otherwise.
         */
        public void callSessionMultipartyStateChanged(ImsCallSession session,
                boolean isMultiParty) {
            // no-op
        }

        /**
         * Called when the session supplementary service is received
         *
         * @param session the session object that carries out the IMS session
         */
        public void callSessionSuppServiceReceived(ImsCallSession session,
                ImsSuppServiceNotification suppServiceInfo) {
        }

        /**
         * Received RTT modify request from Remote Party
         */
        public void callSessionRttModifyRequestReceived(ImsCallSession session,
            ImsCallProfile callProfile) {
            // no-op
        }

        /**
         * Received response for RTT modify request
         */
        public void callSessionRttModifyResponseReceived(int status) {
            // no -op
        }

        /**
         * Device received RTT message from Remote UE
         */
        public void callSessionRttMessageReceived(String rttMessage) {
            // no-op
        }
    }

    private final IImsCallSession miSession;
    private boolean mClosed = false;
    private Listener mListener;

    public ImsCallSession(IImsCallSession iSession) {
        miSession = iSession;

        if (iSession != null) {
            try {
                iSession.setListener(new IImsCallSessionListenerProxy());
            } catch (RemoteException e) {
            }
        } else {
            mClosed = true;
        }
    }

    public ImsCallSession(IImsCallSession iSession, Listener listener) {
        this(iSession);
        setListener(listener);
    }

    /**
     * Closes this object. This object is not usable after being closed.
     */
    public synchronized void close() {
        if (mClosed) {
            return;
        }

        try {
            miSession.close();
            mClosed = true;
        } catch (RemoteException e) {
        }
    }

    /**
     * Gets the call ID of the session.
     *
     * @return the call ID
     */
    public String getCallId() {
        if (mClosed) {
            return null;
        }

        try {
            return miSession.getCallId();
        } catch (RemoteException e) {
            return null;
        }
    }

    /**
     * Gets the call profile that this session is associated with
     *
     * @return the call profile that this session is associated with
     */
    public ImsCallProfile getCallProfile() {
        if (mClosed) {
            return null;
        }

        try {
            return miSession.getCallProfile();
        } catch (RemoteException e) {
            return null;
        }
    }

    /**
     * Gets the local call profile that this session is associated with
     *
     * @return the local call profile that this session is associated with
     */
    public ImsCallProfile getLocalCallProfile() {
        if (mClosed) {
            return null;
        }

        try {
            return miSession.getLocalCallProfile();
        } catch (RemoteException e) {
            return null;
        }
    }

    /**
     * Gets the remote call profile that this session is associated with
     *
     * @return the remote call profile that this session is associated with
     */
    public ImsCallProfile getRemoteCallProfile() {
        if (mClosed) {
            return null;
        }

        try {
            return miSession.getRemoteCallProfile();
        } catch (RemoteException e) {
            return null;
        }
    }

    /**
     * Gets the video call provider for the session.
     *
     * @return The video call provider.
     */
    public IImsVideoCallProvider getVideoCallProvider() {
        if (mClosed) {
            return null;
        }

        try {
            return miSession.getVideoCallProvider();
        } catch (RemoteException e) {
            return null;
        }
    }

    /**
     * Gets the value associated with the specified property of this session.
     *
     * @return the string value associated with the specified property
     */
    public String getProperty(String name) {
        if (mClosed) {
            return null;
        }

        try {
            return miSession.getProperty(name);
        } catch (RemoteException e) {
            return null;
        }
    }

    /**
     * Gets the session state.
     * The value returned must be one of the states in {@link State}.
     *
     * @return the session state
     */
    public int getState() {
        if (mClosed) {
            return State.INVALID;
        }

        try {
            return miSession.getState();
        } catch (RemoteException e) {
            return State.INVALID;
        }
    }

    /**
     * Determines if the {@link ImsCallSession} is currently alive (e.g. not in a terminated or
     * closed state).
     *
     * @return {@code True} if the session is alive.
     */
    public boolean isAlive() {
        if (mClosed) {
            return false;
        }

        int state = getState();
        switch (state) {
            case State.IDLE:
            case State.INITIATED:
            case State.NEGOTIATING:
            case State.ESTABLISHING:
            case State.ESTABLISHED:
            case State.RENEGOTIATING:
            case State.REESTABLISHING:
                return true;
            default:
                return false;
        }
    }

    /**
     * Gets the native IMS call session.
     * @hide
     */
    public IImsCallSession getSession() {
        return miSession;
    }

    /**
     * Checks if the session is in call.
     *
     * @return true if the session is in call
     */
    public boolean isInCall() {
        if (mClosed) {
            return false;
        }

        try {
            return miSession.isInCall();
        } catch (RemoteException e) {
            return false;
        }
    }

    /**
     * Sets the listener to listen to the session events. A {@link ImsCallSession}
     * can only hold one listener at a time. Subsequent calls to this method
     * override the previous listener.
     *
     * @param listener to listen to the session events of this object
     */
    public void setListener(Listener listener) {
        mListener = listener;
    }

    /**
     * Mutes or unmutes the mic for the active call.
     *
     * @param muted true if the call is muted, false otherwise
     */
    public void setMute(boolean muted) {
        if (mClosed) {
            return;
        }

        try {
            miSession.setMute(muted);
        } catch (RemoteException e) {
        }
    }

    /**
     * Initiates an IMS call with the specified target and call profile.
     * The session listener is called back upon defined session events.
     * The method is only valid to call when the session state is in
     * {@link ImsCallSession.State#IDLE}.
     *
     * @param callee dialed string to make the call to
     * @param profile call profile to make the call with the specified service type,
     *      call type and media information
     * @see Listener#callSessionStarted, Listener#callSessionStartFailed
     */
    public void start(String callee, ImsCallProfile profile) {
        if (mClosed) {
            return;
        }

        try {
            miSession.start(callee, profile);
        } catch (RemoteException e) {
        }
    }

    /**
     * Initiates an IMS conference call with the specified target and call profile.
     * The session listener is called back upon defined session events.
     * The method is only valid to call when the session state is in
     * {@link ImsCallSession.State#IDLE}.
     *
     * @param participants participant list to initiate an IMS conference call
     * @param profile call profile to make the call with the specified service type,
     *      call type and media information
     * @see Listener#callSessionStarted, Listener#callSessionStartFailed
     */
    public void start(String[] participants, ImsCallProfile profile) {
        if (mClosed) {
            return;
        }

        try {
            miSession.startConference(participants, profile);
        } catch (RemoteException e) {
        }
    }

    /**
     * Accepts an incoming call or session update.
     *
     * @param callType call type specified in {@link ImsCallProfile} to be answered
     * @param profile stream media profile {@link ImsStreamMediaProfile} to be answered
     * @see Listener#callSessionStarted
     */
    public void accept(int callType, ImsStreamMediaProfile profile) {
        if (mClosed) {
            return;
        }

        try {
            miSession.accept(callType, profile);
        } catch (RemoteException e) {
        }
    }

    /**
     * Rejects an incoming call or session update.
     *
     * @param reason reason code to reject an incoming call
     * @see Listener#callSessionStartFailed
     */
    public void reject(int reason) {
        if (mClosed) {
            return;
        }

        try {
            miSession.reject(reason);
        } catch (RemoteException e) {
        }
    }

    /**
     * Terminates a call.
     *
     * @see Listener#callSessionTerminated
     */
    public void terminate(int reason) {
        if (mClosed) {
            return;
        }

        try {
            miSession.terminate(reason);
        } catch (RemoteException e) {
        }
    }

    /**
     * Puts a call on hold. When it succeeds, {@link Listener#callSessionHeld} is called.
     *
     * @param profile stream media profile {@link ImsStreamMediaProfile} to hold the call
     * @see Listener#callSessionHeld, Listener#callSessionHoldFailed
     */
    public void hold(ImsStreamMediaProfile profile) {
        if (mClosed) {
            return;
        }

        try {
            miSession.hold(profile);
        } catch (RemoteException e) {
        }
    }

    /**
     * Continues a call that's on hold. When it succeeds,
     * {@link Listener#callSessionResumed} is called.
     *
     * @param profile stream media profile {@link ImsStreamMediaProfile} to resume the call
     * @see Listener#callSessionResumed, Listener#callSessionResumeFailed
     */
    public void resume(ImsStreamMediaProfile profile) {
        if (mClosed) {
            return;
        }

        try {
            miSession.resume(profile);
        } catch (RemoteException e) {
        }
    }

    /**
     * Merges the active & hold call. When it succeeds,
     * {@link Listener#callSessionMergeStarted} is called.
     *
     * @see Listener#callSessionMergeStarted , Listener#callSessionMergeFailed
     */
    public void merge() {
        if (mClosed) {
            return;
        }

        try {
            miSession.merge();
        } catch (RemoteException e) {
        }
    }

    /**
     * Updates the current call's properties (ex. call mode change: video upgrade / downgrade).
     *
     * @param callType call type specified in {@link ImsCallProfile} to be updated
     * @param profile stream media profile {@link ImsStreamMediaProfile} to be updated
     * @see Listener#callSessionUpdated, Listener#callSessionUpdateFailed
     */
    public void update(int callType, ImsStreamMediaProfile profile) {
        if (mClosed) {
            return;
        }

        try {
            miSession.update(callType, profile);
        } catch (RemoteException e) {
        }
    }

    /**
     * Extends this call to the conference call with the specified recipients.
     *
     * @param participants list to be invited to the conference call after extending the call
     * @see Listener#callSessionConferenceExtended
     * @see Listener#callSessionConferenceExtendFailed
     */
    public void extendToConference(String[] participants) {
        if (mClosed) {
            return;
        }

        try {
            miSession.extendToConference(participants);
        } catch (RemoteException e) {
        }
    }

    /**
     * Requests the conference server to invite an additional participants to the conference.
     *
     * @param participants list to be invited to the conference call
     * @see Listener#callSessionInviteParticipantsRequestDelivered
     * @see Listener#callSessionInviteParticipantsRequestFailed
     */
    public void inviteParticipants(String[] participants) {
        if (mClosed) {
            return;
        }

        try {
            miSession.inviteParticipants(participants);
        } catch (RemoteException e) {
        }
    }

    /**
     * Requests the conference server to remove the specified participants from the conference.
     *
     * @param participants participant list to be removed from the conference call
     * @see Listener#callSessionRemoveParticipantsRequestDelivered
     * @see Listener#callSessionRemoveParticipantsRequestFailed
     */
    public void removeParticipants(String[] participants) {
        if (mClosed) {
            return;
        }

        try {
            miSession.removeParticipants(participants);
        } catch (RemoteException e) {
        }
    }


    /**
     * Sends a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833</a>,
     * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15,
     * and event flash to 16. Currently, event flash is not supported.
     *
     * @param c the DTMF to send. '0' ~ '9', 'A' ~ 'D', '*', '#' are valid inputs.
     */
    public void sendDtmf(char c, Message result) {
        if (mClosed) {
            return;
        }

        try {
            miSession.sendDtmf(c, result);
        } catch (RemoteException e) {
        }
    }

    /**
     * Starts a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833</a>,
     * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15,
     * and event flash to 16. Currently, event flash is not supported.
     *
     * @param c the DTMF to send. '0' ~ '9', 'A' ~ 'D', '*', '#' are valid inputs.
     */
    public void startDtmf(char c) {
        if (mClosed) {
            return;
        }

        try {
            miSession.startDtmf(c);
        } catch (RemoteException e) {
        }
    }

    /**
     * Stops a DTMF code.
     */
    public void stopDtmf() {
        if (mClosed) {
            return;
        }

        try {
            miSession.stopDtmf();
        } catch (RemoteException e) {
        }
    }

    /**
     * Sends an USSD message.
     *
     * @param ussdMessage USSD message to send
     */
    public void sendUssd(String ussdMessage) {
        if (mClosed) {
            return;
        }

        try {
            miSession.sendUssd(ussdMessage);
        } catch (RemoteException e) {
        }
    }

    /**
     * Determines if the session is multiparty.
     *
     * @return {@code True} if the session is multiparty.
     */
    public boolean isMultiparty() {
        if (mClosed) {
            return false;
        }

        try {
            return miSession.isMultiparty();
        } catch (RemoteException e) {
            return false;
        }
    }

    /**
     * Sends Rtt Message
     *
     * @param rttMessage rtt text to be sent
     * @throws ImsException if call is absent
     */
    public void sendRttMessage(String rttMessage) {
        if (mClosed) {
            return;
        }

        try {
            miSession.sendRttMessage(rttMessage);
        } catch (RemoteException e) {
        }
    }

    /**
     * Sends RTT Upgrade request
     *
     * @param to   : expected profile
     * @throws CallStateException
     */
    public void sendRttModifyRequest(ImsCallProfile to) {
        if (mClosed) {
            return;
        }

        try {
            miSession.sendRttModifyRequest(to);
        } catch (RemoteException e) {
        }
    }

    /**
     * Sends RTT Upgrade response
     *
     * @param response : response for upgrade
     * @throws CallStateException
     */
    public void sendRttModifyResponse(boolean response) {
        if (mClosed) {
            return;
        }

        try {
            miSession.sendRttModifyResponse(response);
        } catch (RemoteException e) {
        }
    }

    /**
     * A listener type for receiving notification on IMS call session events.
     * When an event is generated for an {@link IImsCallSession},
     * the application is notified by having one of the methods called on
     * the {@link IImsCallSessionListener}.
     */
    private class IImsCallSessionListenerProxy extends ImsCallSessionListenerImplBase {
        /**
         * Notifies the result of the basic session operation (setup / terminate).
         */
        @Override
        public void callSessionProgressing(IImsCallSession session,
                ImsStreamMediaProfile profile) {
            if (mListener != null) {
                mListener.callSessionProgressing(ImsCallSession.this, profile);
            }
        }

        @Override
        public void callSessionStarted(IImsCallSession session,
                ImsCallProfile profile) {
            if (mListener != null) {
                mListener.callSessionStarted(ImsCallSession.this, profile);
            }
        }

        @Override
        public void callSessionStartFailed(IImsCallSession session,
                ImsReasonInfo reasonInfo) {
            if (mListener != null) {
                mListener.callSessionStartFailed(ImsCallSession.this, reasonInfo);
            }
        }

        @Override
        public void callSessionTerminated(IImsCallSession session,
                ImsReasonInfo reasonInfo) {
            if (mListener != null) {
                mListener.callSessionTerminated(ImsCallSession.this, reasonInfo);
            }
        }

        /**
         * Notifies the result of the call hold/resume operation.
         */
        @Override
        public void callSessionHeld(IImsCallSession session,
                ImsCallProfile profile) {
            if (mListener != null) {
                mListener.callSessionHeld(ImsCallSession.this, profile);
            }
        }

        @Override
        public void callSessionHoldFailed(IImsCallSession session,
                ImsReasonInfo reasonInfo) {
            if (mListener != null) {
                mListener.callSessionHoldFailed(ImsCallSession.this, reasonInfo);
            }
        }

        @Override
        public void callSessionHoldReceived(IImsCallSession session,
                ImsCallProfile profile) {
            if (mListener != null) {
                mListener.callSessionHoldReceived(ImsCallSession.this, profile);
            }
        }

        @Override
        public void callSessionResumed(IImsCallSession session,
                ImsCallProfile profile) {
            if (mListener != null) {
                mListener.callSessionResumed(ImsCallSession.this, profile);
            }
        }

        @Override
        public void callSessionResumeFailed(IImsCallSession session,
                ImsReasonInfo reasonInfo) {
            if (mListener != null) {
                mListener.callSessionResumeFailed(ImsCallSession.this, reasonInfo);
            }
        }

        @Override
        public void callSessionResumeReceived(IImsCallSession session,
                ImsCallProfile profile) {
            if (mListener != null) {
                mListener.callSessionResumeReceived(ImsCallSession.this, profile);
            }
        }

        /**
         * Notifies the start of a call merge operation.
         *
         * @param session The call session.
         * @param newSession The merged call session.
         * @param profile The call profile.
         */
        @Override
        public void callSessionMergeStarted(IImsCallSession session,
                IImsCallSession newSession, ImsCallProfile profile) {
            // This callback can be used for future use to add additional
            // functionality that may be needed between conference start and complete
            Log.d(TAG, "callSessionMergeStarted");
        }

        /**
         * Notifies the successful completion of a call merge operation.
         *
         * @param newSession The call session.
         */
        @Override
        public void callSessionMergeComplete(IImsCallSession newSession) {
            if (mListener != null) {
                if (newSession != null) {
                    // Check if the active session is the same session that was
                    // active before the merge request was sent.
                    ImsCallSession validActiveSession = ImsCallSession.this;
                    try {
                        if (!Objects.equals(miSession.getCallId(), newSession.getCallId())) {
                            // New session created after conference
                            validActiveSession = new ImsCallSession(newSession);
                        }
                    } catch (RemoteException rex) {
                        Log.e(TAG, "callSessionMergeComplete: exception for getCallId!");
                    }
                    mListener.callSessionMergeComplete(validActiveSession);
               } else {
                   // Session already exists. Hence no need to pass
                   mListener.callSessionMergeComplete(null);
               }
            }
        }

        /**
         * Notifies of a failure to perform a call merge operation.
         *
         * @param session The call session.
         * @param reasonInfo The merge failure reason.
         */
        @Override
        public void callSessionMergeFailed(IImsCallSession session,
                ImsReasonInfo reasonInfo) {
            if (mListener != null) {
                mListener.callSessionMergeFailed(ImsCallSession.this, reasonInfo);
            }
        }

        /**
         * Notifies the result of call upgrade / downgrade or any other call updates.
         */
        @Override
        public void callSessionUpdated(IImsCallSession session,
                ImsCallProfile profile) {
            if (mListener != null) {
                mListener.callSessionUpdated(ImsCallSession.this, profile);
            }
        }

        @Override
        public void callSessionUpdateFailed(IImsCallSession session,
                ImsReasonInfo reasonInfo) {
            if (mListener != null) {
                mListener.callSessionUpdateFailed(ImsCallSession.this, reasonInfo);
            }
        }

        @Override
        public void callSessionUpdateReceived(IImsCallSession session,
                ImsCallProfile profile) {
            if (mListener != null) {
                mListener.callSessionUpdateReceived(ImsCallSession.this, profile);
            }
        }

        /**
         * Notifies the result of conference extension.
         */
        @Override
        public void callSessionConferenceExtended(IImsCallSession session,
                IImsCallSession newSession, ImsCallProfile profile) {
            if (mListener != null) {
                mListener.callSessionConferenceExtended(ImsCallSession.this,
                        new ImsCallSession(newSession), profile);
            }
        }

        @Override
        public void callSessionConferenceExtendFailed(IImsCallSession session,
                ImsReasonInfo reasonInfo) {
            if (mListener != null) {
                mListener.callSessionConferenceExtendFailed(ImsCallSession.this, reasonInfo);
            }
        }

        @Override
        public void callSessionConferenceExtendReceived(IImsCallSession session,
                IImsCallSession newSession, ImsCallProfile profile) {
            if (mListener != null) {
                mListener.callSessionConferenceExtendReceived(ImsCallSession.this,
                        new ImsCallSession(newSession), profile);
            }
        }

        /**
         * Notifies the result of the participant invitation / removal to/from
         * the conference session.
         */
        @Override
        public void callSessionInviteParticipantsRequestDelivered(IImsCallSession session) {
            if (mListener != null) {
                mListener.callSessionInviteParticipantsRequestDelivered(ImsCallSession.this);
            }
        }

        @Override
        public void callSessionInviteParticipantsRequestFailed(IImsCallSession session,
                ImsReasonInfo reasonInfo) {
            if (mListener != null) {
                mListener.callSessionInviteParticipantsRequestFailed(ImsCallSession.this,
                        reasonInfo);
            }
        }

        @Override
        public void callSessionRemoveParticipantsRequestDelivered(IImsCallSession session) {
            if (mListener != null) {
                mListener.callSessionRemoveParticipantsRequestDelivered(ImsCallSession.this);
            }
        }

        @Override
        public void callSessionRemoveParticipantsRequestFailed(IImsCallSession session,
                ImsReasonInfo reasonInfo) {
            if (mListener != null) {
                mListener.callSessionRemoveParticipantsRequestFailed(ImsCallSession.this,
                        reasonInfo);
            }
        }

        /**
         * Notifies the changes of the conference info. in the conference session.
         */
        @Override
        public void callSessionConferenceStateUpdated(IImsCallSession session,
                ImsConferenceState state) {
            if (mListener != null) {
                mListener.callSessionConferenceStateUpdated(ImsCallSession.this, state);
            }
        }

        /**
         * Notifies the incoming USSD message.
         */
        @Override
        public void callSessionUssdMessageReceived(IImsCallSession session,
                int mode, String ussdMessage) {
            if (mListener != null) {
                mListener.callSessionUssdMessageReceived(ImsCallSession.this, mode, ussdMessage);
            }
        }

        /**
         * Notifies of handover information for this call
         */
        @Override
        public void callSessionHandover(IImsCallSession session,
                                 int srcAccessTech, int targetAccessTech,
                                 ImsReasonInfo reasonInfo) {
            if (mListener != null) {
                mListener.callSessionHandover(ImsCallSession.this, srcAccessTech,
                        targetAccessTech, reasonInfo);
            }
        }

        /**
         * Notifies of handover failure info for this call
         */
        @Override
        public void callSessionHandoverFailed(IImsCallSession session,
                                       int srcAccessTech, int targetAccessTech,
                                       ImsReasonInfo reasonInfo) {
            if (mListener != null) {
                mListener.callSessionHandoverFailed(ImsCallSession.this, srcAccessTech,
                        targetAccessTech, reasonInfo);
            }
        }

        /**
         * Notifies the TTY mode received from remote party.
         */
        @Override
        public void callSessionTtyModeReceived(IImsCallSession session,
                int mode) {
            if (mListener != null) {
                mListener.callSessionTtyModeReceived(ImsCallSession.this, mode);
            }
        }

        /**
         * Notifies of a change to the multiparty state for this {@code ImsCallSession}.
         *
         * @param session The call session.
         * @param isMultiParty {@code true} if the session became multiparty, {@code false}
         *      otherwise.
         */
        public void callSessionMultipartyStateChanged(IImsCallSession session,
                boolean isMultiParty) {

            if (mListener != null) {
                mListener.callSessionMultipartyStateChanged(ImsCallSession.this, isMultiParty);
            }
        }

        @Override
        public void callSessionSuppServiceReceived(IImsCallSession session,
                ImsSuppServiceNotification suppServiceInfo ) {
            if (mListener != null) {
                mListener.callSessionSuppServiceReceived(ImsCallSession.this, suppServiceInfo);
            }
        }

        /**
         * Received RTT modify request from remote party
         */
        @Override
        public void callSessionRttModifyRequestReceived(IImsCallSession session,
                ImsCallProfile callProfile) {
            if (mListener != null) {
                mListener.callSessionRttModifyRequestReceived(ImsCallSession.this, callProfile);
            }
        }

        /**
         * Received response for RTT modify request
         */
        @Override
        public void callSessionRttModifyResponseReceived(int status) {
            if (mListener != null) {
                mListener.callSessionRttModifyResponseReceived(status);
            }
        }

        /**
         * RTT Message received
         */
        @Override
        public void callSessionRttMessageReceived(String rttMessage) {
            if (mListener != null) {
                mListener.callSessionRttMessageReceived(rttMessage);
            }
        }
    }

    /**
     * Provides a string representation of the {@link ImsCallSession}.  Primarily intended for
     * use in log statements.
     *
     * @return String representation of session.
     */
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[ImsCallSession objId:");
        sb.append(System.identityHashCode(this));
        sb.append(" state:");
        sb.append(State.toString(getState()));
        sb.append(" callId:");
        sb.append(getCallId());
        sb.append("]");
        return sb.toString();
    }
}
