/*
 * 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) {
        }
    }

    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;
        }
    }

    /**
     * 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);
            }
        }

    }

    /**
     * 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();
    }
}
