/*
 * 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.telephony.ims.aidl.IImsCallSessionListener;
import android.telephony.ims.ImsCallProfile;
import android.telephony.ims.ImsStreamMediaProfile;
import android.telephony.ims.RtpHeaderExtension;

import com.android.ims.internal.IImsVideoCallProvider;

/**
 * An IMS session that is associated with a SIP dialog which is established from/to
 * INVITE request or a mid-call transaction to control the session.
 * @hide
 */
interface IImsCallSession {
    /**
     * Closes the object. This object is not usable after being closed.
     */
    void close();

    /**
     * Gets the call ID of the session.
     *
     * @return the call ID
     */
    String getCallId();

    /**
     * Gets the call profile that this session is associated with
     *
     * @return the call profile that this session is associated with
     */
    ImsCallProfile getCallProfile();

    /**
     * Gets the local call profile that this session is associated with
     *
     * @return the local call profile that this session is associated with
     */
    ImsCallProfile getLocalCallProfile();

    /**
     * Gets the remote call profile that this session is associated with
     *
     * @return the remote call profile that this session is associated with
     */
    ImsCallProfile getRemoteCallProfile();

    /**
     * Gets the value associated with the specified property of this session.
     *
     * @return the string value associated with the specified property
     */
    String getProperty(String name);

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

    /**
     * Checks if the session is in a call.
     *
     * @return true if the session is in a call
     */
    boolean isInCall();

    /**
     * Sets the listener to listen to the session events. A {@link IImsCallSession}
     * 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
     *
     * @deprecated This is depreacated.
     */
    void setListener(in IImsCallSessionListener listener);

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

    /**
     * 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
     */
    void start(String callee, in ImsCallProfile profile);

    /**
     * Initiates an IMS call with the specified participants 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
     */
    void startConference(in String[] participants, in ImsCallProfile profile);

    /**
     * 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
     */
    void accept(int callType, in ImsStreamMediaProfile profile);

    /**
     * Deflects an incoming call.
     *
     * @param deflectNumber number to deflect the call
     */
    void deflect(String deflectNumber);

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

    /**
     * Transfer an established call to given number
     *
     * @param number number to transfer the call
     * @param isConfirmationRequired if {@code True}, indicates a confirmed transfer,
     * if {@code False} it indicates an unconfirmed transfer.
     */
    void transfer(String number, boolean isConfirmationRequired);

    /**
     * Transfer an established call to another call session
     *
     * @param transferToSession The other ImsCallSession to transfer the ongoing session to.
     */
    void consultativeTransfer(in IImsCallSession transferToSession);

    /**
     * Terminates a call.
     *
     * @see Listener#callSessionTerminated
     */
    void terminate(int reason);

    /**
     * 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
     */
    void hold(in ImsStreamMediaProfile profile);

    /**
     * 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
     */
    void resume(in ImsStreamMediaProfile profile);

    /**
     * Merges the active & hold call. When the merge starts,
     * {@link Listener#callSessionMergeStarted} is called.
     * {@link Listener#callSessionMergeComplete} is called if the merge is successful, and
     * {@link Listener#callSessionMergeFailed} is called if the merge fails.
     *
     * @see Listener#callSessionMergeStarted, Listener#callSessionMergeComplete,
     *      Listener#callSessionMergeFailed
     */
    void merge();

    /**
     * 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
     */
    void update(int callType, in ImsStreamMediaProfile profile);

    /**
     * Extends this call to the conference call with the specified recipients.
     *
     * @param participants participant list to be invited to the conference call after extending the call
     * @see Listener#sessionConferenceExtened, Listener#sessionConferenceExtendFailed
     */
    void extendToConference(in String[] participants);

    /**
     * Requests the conference server to invite an additional participants to the conference.
     *
     * @param participants participant list to be invited to the conference call
     * @see Listener#sessionInviteParticipantsRequestDelivered,
     *      Listener#sessionInviteParticipantsRequestFailed
     */
    void inviteParticipants(in String[] participants);

    /**
     * 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#sessionRemoveParticipantsRequestDelivered,
     *      Listener#sessionRemoveParticipantsRequestFailed
     */
    void removeParticipants(in String[] participants);

    /**
     * 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.
     * @param result.
     */
    void sendDtmf(char c, in Message result);

    /**
     * Start 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.
     */
    void startDtmf(char c);

    /**
     * Stop a DTMF code.
     */
    void stopDtmf();

    /**
     * Sends an USSD message.
     *
     * @param ussdMessage USSD message to send
     */
    void sendUssd(String ussdMessage);

    /**
     * Returns a binder for the video call provider implementation contained within the IMS service
     * process. This binder is used by the VideoCallProvider subclass in Telephony which
     * intermediates between the propriety implementation and Telecomm/InCall.
     */
    IImsVideoCallProvider getVideoCallProvider();

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

    /**
     * Device issues RTT modify request
     * @param toProfile The profile with requested changes made
     */
    void sendRttModifyRequest(in ImsCallProfile toProfile);

    /*
     * Device responds to Remote RTT modify request
     * @param status true : Accepted the request
     *                false : Declined the request
     */
    void sendRttModifyResponse(in boolean status);

    /*
     * Device sends RTT message
     * @param rttMessage RTT message to be sent
     */
    void sendRttMessage(in String rttMessage);

    /*
     * Device sends RTP header extension(s).
     * @param extensions the header extensions to be sent
     */
    void sendRtpHeaderExtensions(in List<RtpHeaderExtension> extensions);

    /*
     * Deliver the bitrate for the indicated media type, direction and bitrate to the upper layer.
     *
     * @param mediaType MediaType is used to identify media stream such as audio or video.
     * @param direction Direction of this packet stream (e.g. uplink or downlink).
     * @param bitsPerSecond This value is the bitrate received from the NW through the Recommended
     *        bitrate MAC Control Element message and ImsStack converts this value from MAC bitrate
     *        to audio/video codec bitrate (defined in TS26.114).
     */
    void callSessionNotifyAnbr(int mediaType, int direction, int bitsPerSecond);
}
