Home | History | Annotate | Download | only in internal
      1 /*
      2  * Copyright (c) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.ims.internal;
     18 
     19 import android.os.RemoteException;
     20 
     21 import com.android.ims.ImsCallProfile;
     22 import com.android.ims.ImsConferenceState;
     23 import com.android.ims.ImsReasonInfo;
     24 import com.android.ims.ImsStreamMediaProfile;
     25 
     26 /**
     27  * Provides the call initiation/termination, and media exchange between two IMS endpoints.
     28  * It directly communicates with IMS service which implements the IMS protocol behavior.
     29  *
     30  * @hide
     31  */
     32 public class ImsCallSession {
     33     private static final String TAG = "ImsCallSession";
     34 
     35     /**
     36      * Defines IMS call session state.
     37      */
     38     public static class State {
     39         public static final int IDLE = 0;
     40         public static final int INITIATED = 1;
     41         public static final int NEGOTIATING = 2;
     42         public static final int ESTABLISHING = 3;
     43         public static final int ESTABLISHED = 4;
     44 
     45         public static final int RENEGOTIATING = 5;
     46         public static final int REESTABLISHING = 6;
     47 
     48         public static final int TERMINATING = 7;
     49         public static final int TERMINATED = 8;
     50 
     51         public static final int INVALID = (-1);
     52 
     53         /**
     54          * Converts the state to string.
     55          */
     56         public static String toString(int state) {
     57             switch (state) {
     58                 case IDLE:
     59                     return "IDLE";
     60                 case INITIATED:
     61                     return "INITIATED";
     62                 case NEGOTIATING:
     63                     return "NEGOTIATING";
     64                 case ESTABLISHING:
     65                     return "ESTABLISHING";
     66                 case ESTABLISHED:
     67                     return "ESTABLISHED";
     68                 case RENEGOTIATING:
     69                     return "RENEGOTIATING";
     70                 case REESTABLISHING:
     71                     return "REESTABLISHING";
     72                 case TERMINATING:
     73                     return "TERMINATING";
     74                 case TERMINATED:
     75                     return "TERMINATED";
     76                 default:
     77                     return "UNKNOWN";
     78             }
     79         }
     80 
     81         private State() {
     82         }
     83     }
     84 
     85     /**
     86      * Listener for events relating to an IMS session, such as when a session is being
     87      * recieved ("on ringing") or a call is outgoing ("on calling").
     88      * <p>Many of these events are also received by {@link ImsCall.Listener}.</p>
     89      */
     90     public static class Listener {
     91         /**
     92          * Called when a request is sent out to initiate a new session
     93          * and 1xx response is received from the network.
     94          *
     95          * @param session the session object that carries out the IMS session
     96          */
     97         public void callSessionProgressing(ImsCallSession session,
     98                 ImsStreamMediaProfile profile) {
     99             // no-op
    100         }
    101 
    102         /**
    103          * Called when the session is established.
    104          *
    105          * @param session the session object that carries out the IMS session
    106          */
    107         public void callSessionStarted(ImsCallSession session,
    108                 ImsCallProfile profile) {
    109             // no-op
    110         }
    111 
    112         /**
    113          * Called when the session establishment is failed.
    114          *
    115          * @param session the session object that carries out the IMS session
    116          * @param reasonInfo detailed reason of the session establishment failure
    117          */
    118         public void callSessionStartFailed(ImsCallSession session,
    119                 ImsReasonInfo reasonInfo) {
    120         }
    121 
    122         /**
    123          * Called when the session is terminated.
    124          *
    125          * @param session the session object that carries out the IMS session
    126          * @param reasonInfo detailed reason of the session termination
    127          */
    128         public void callSessionTerminated(ImsCallSession session,
    129                 ImsReasonInfo reasonInfo) {
    130         }
    131 
    132         /**
    133          * Called when the session is in hold.
    134          *
    135          * @param session the session object that carries out the IMS session
    136          */
    137         public void callSessionHeld(ImsCallSession session,
    138                 ImsCallProfile profile) {
    139         }
    140 
    141         /**
    142          * Called when the session hold is failed.
    143          *
    144          * @param session the session object that carries out the IMS session
    145          * @param reasonInfo detailed reason of the session hold failure
    146          */
    147         public void callSessionHoldFailed(ImsCallSession session,
    148                 ImsReasonInfo reasonInfo) {
    149         }
    150 
    151         /**
    152          * Called when the session hold is received from the remote user.
    153          *
    154          * @param session the session object that carries out the IMS session
    155          */
    156         public void callSessionHoldReceived(ImsCallSession session,
    157                 ImsCallProfile profile) {
    158         }
    159 
    160         /**
    161          * Called when the session resume is done.
    162          *
    163          * @param session the session object that carries out the IMS session
    164          */
    165         public void callSessionResumed(ImsCallSession session,
    166                 ImsCallProfile profile) {
    167         }
    168 
    169         /**
    170          * Called when the session resume is failed.
    171          *
    172          * @param session the session object that carries out the IMS session
    173          * @param reasonInfo detailed reason of the session resume failure
    174          */
    175         public void callSessionResumeFailed(ImsCallSession session,
    176                 ImsReasonInfo reasonInfo) {
    177         }
    178 
    179         /**
    180          * Called when the session resume is received from the remote user.
    181          *
    182          * @param session the session object that carries out the IMS session
    183          */
    184         public void callSessionResumeReceived(ImsCallSession session,
    185                 ImsCallProfile profile) {
    186         }
    187 
    188         /**
    189          * Called when the session merge is done.
    190          *
    191          * @param session the session object that carries out the IMS session
    192          * @param newSession the session object that is merged with an active & hold session
    193          */
    194         public void callSessionMerged(ImsCallSession session,
    195                 ImsCallSession newSession, ImsCallProfile profile) {
    196         }
    197 
    198         /**
    199          * Called when the session merge is failed.
    200          *
    201          * @param session the session object that carries out the IMS session
    202          * @param reasonInfo detailed reason of the call merge failure
    203          */
    204         public void callSessionMergeFailed(ImsCallSession session,
    205                 ImsReasonInfo reasonInfo) {
    206         }
    207 
    208         /**
    209          * Called when the session is updated (except for hold/unhold).
    210          *
    211          * @param call the call object that carries out the IMS call
    212          */
    213         public void callSessionUpdated(ImsCallSession session,
    214                 ImsCallProfile profile) {
    215         }
    216 
    217         /**
    218          * Called when the session update is failed.
    219          *
    220          * @param session the session object that carries out the IMS session
    221          * @param reasonInfo detailed reason of the session update failure
    222          */
    223         public void callSessionUpdateFailed(ImsCallSession session,
    224                 ImsReasonInfo reasonInfo) {
    225         }
    226 
    227         /**
    228          * Called when the session update is received from the remote user.
    229          *
    230          * @param session the session object that carries out the IMS session
    231          */
    232         public void callSessionUpdateReceived(ImsCallSession session,
    233                 ImsCallProfile profile) {
    234             // no-op
    235         }
    236 
    237         /**
    238          * Called when the session is extended to the conference session.
    239          *
    240          * @param session the session object that carries out the IMS session
    241          * @param newSession the session object that is extended to the conference
    242          *      from the active session
    243          */
    244         public void callSessionConferenceExtended(ImsCallSession session,
    245                 ImsCallSession newSession, ImsCallProfile profile) {
    246         }
    247 
    248         /**
    249          * Called when the conference extension is failed.
    250          *
    251          * @param session the session object that carries out the IMS session
    252          * @param reasonInfo detailed reason of the conference extension failure
    253          */
    254         public void callSessionConferenceExtendFailed(ImsCallSession session,
    255                 ImsReasonInfo reasonInfo) {
    256         }
    257 
    258         /**
    259          * Called when the conference extension is received from the remote user.
    260          *
    261          * @param session the session object that carries out the IMS session
    262          */
    263         public void callSessionConferenceExtendReceived(ImsCallSession session,
    264                 ImsCallSession newSession, ImsCallProfile profile) {
    265             // no-op
    266         }
    267 
    268         /**
    269          * Called when the invitation request of the participants is delivered to the conference
    270          * server.
    271          *
    272          * @param session the session object that carries out the IMS session
    273          */
    274         public void callSessionInviteParticipantsRequestDelivered(ImsCallSession session) {
    275             // no-op
    276         }
    277 
    278         /**
    279          * Called when the invitation request of the participants is failed.
    280          *
    281          * @param session the session object that carries out the IMS session
    282          * @param reasonInfo detailed reason of the conference invitation failure
    283          */
    284         public void callSessionInviteParticipantsRequestFailed(ImsCallSession session,
    285                 ImsReasonInfo reasonInfo) {
    286             // no-op
    287         }
    288 
    289         /**
    290          * Called when the removal request of the participants is delivered to the conference
    291          * server.
    292          *
    293          * @param session the session object that carries out the IMS session
    294          */
    295         public void callSessionRemoveParticipantsRequestDelivered(ImsCallSession session) {
    296             // no-op
    297         }
    298 
    299         /**
    300          * Called when the removal request of the participants is failed.
    301          *
    302          * @param session the session object that carries out the IMS session
    303          * @param reasonInfo detailed reason of the conference removal failure
    304          */
    305         public void callSessionRemoveParticipantsRequestFailed(ImsCallSession session,
    306                 ImsReasonInfo reasonInfo) {
    307             // no-op
    308         }
    309 
    310         /**
    311          * Called when the conference state is updated.
    312          *
    313          * @param session the session object that carries out the IMS session
    314          */
    315         public void callSessionConferenceStateUpdated(ImsCallSession session,
    316                 ImsConferenceState state) {
    317             // no-op
    318         }
    319 
    320         /**
    321          * Called when the USSD message is received from the network.
    322          *
    323          * @param mode mode of the USSD message (REQUEST / NOTIFY)
    324          * @param ussdMessage USSD message
    325          */
    326         public void callSessionUssdMessageReceived(ImsCallSession session,
    327                 int mode, String ussdMessage) {
    328             // no-op
    329         }
    330 
    331         /**
    332          * Called when session access technology changes
    333          *
    334          * @param session IMS session object
    335          * @param srcAccessTech original access technology
    336          * @param targetAccessTech new access technology
    337          * @param reasonInfo
    338          */
    339         public void callSessionHandover(ImsCallSession session,
    340                                  int srcAccessTech, int targetAccessTech,
    341                                  ImsReasonInfo reasonInfo) {
    342             // no-op
    343         }
    344 
    345         /**
    346          * Called when session access technology change fails
    347          *
    348          * @param session IMS session object
    349          * @param srcAccessTech original access technology
    350          * @param targetAccessTech new access technology
    351          * @param reasonInfo handover failure reason
    352          */
    353         public void callSessionHandoverFailed(ImsCallSession session,
    354                                        int srcAccessTech, int targetAccessTech,
    355                                        ImsReasonInfo reasonInfo) {
    356             // no-op
    357         }
    358     }
    359 
    360     private final IImsCallSession miSession;
    361     private boolean mClosed = false;
    362     private Listener mListener;
    363 
    364     public ImsCallSession(IImsCallSession iSession) {
    365         miSession = iSession;
    366 
    367         if (iSession != null) {
    368             try {
    369                 iSession.setListener(new IImsCallSessionListenerProxy());
    370             } catch (RemoteException e) {
    371             }
    372         } else {
    373             mClosed = true;
    374         }
    375     }
    376 
    377     public ImsCallSession(IImsCallSession iSession, Listener listener) {
    378         this(iSession);
    379         setListener(listener);
    380     }
    381 
    382     /**
    383      * Closes this object. This object is not usable after being closed.
    384      */
    385     public synchronized void close() {
    386         if (mClosed) {
    387             return;
    388         }
    389 
    390         try {
    391             miSession.close();
    392             mClosed = true;
    393         } catch (RemoteException e) {
    394         }
    395     }
    396 
    397     /**
    398      * Gets the call ID of the session.
    399      *
    400      * @return the call ID
    401      */
    402     public String getCallId() {
    403         if (mClosed) {
    404             return null;
    405         }
    406 
    407         try {
    408             return miSession.getCallId();
    409         } catch (RemoteException e) {
    410             return null;
    411         }
    412     }
    413 
    414     /**
    415      * Gets the call profile that this session is associated with
    416      *
    417      * @return the call profile that this session is associated with
    418      */
    419     public ImsCallProfile getCallProfile() {
    420         if (mClosed) {
    421             return null;
    422         }
    423 
    424         try {
    425             return miSession.getCallProfile();
    426         } catch (RemoteException e) {
    427             return null;
    428         }
    429     }
    430 
    431     /**
    432      * Gets the local call profile that this session is associated with
    433      *
    434      * @return the local call profile that this session is associated with
    435      */
    436     public ImsCallProfile getLocalCallProfile() {
    437         if (mClosed) {
    438             return null;
    439         }
    440 
    441         try {
    442             return miSession.getLocalCallProfile();
    443         } catch (RemoteException e) {
    444             return null;
    445         }
    446     }
    447 
    448     /**
    449      * Gets the video call provider for the session.
    450      *
    451      * @return The video call provider.
    452      */
    453     public IImsVideoCallProvider getVideoCallProvider() {
    454         if (mClosed) {
    455             return null;
    456         }
    457 
    458         try {
    459             return miSession.getVideoCallProvider();
    460         } catch (RemoteException e) {
    461             return null;
    462         }
    463     }
    464 
    465     /**
    466      * Gets the value associated with the specified property of this session.
    467      *
    468      * @return the string value associated with the specified property
    469      */
    470     public String getProperty(String name) {
    471         if (mClosed) {
    472             return null;
    473         }
    474 
    475         try {
    476             return miSession.getProperty(name);
    477         } catch (RemoteException e) {
    478             return null;
    479         }
    480     }
    481 
    482     /**
    483      * Gets the session state.
    484      * The value returned must be one of the states in {@link State}.
    485      *
    486      * @return the session state
    487      */
    488     public int getState() {
    489         if (mClosed) {
    490             return State.INVALID;
    491         }
    492 
    493         try {
    494             return miSession.getState();
    495         } catch (RemoteException e) {
    496             return State.INVALID;
    497         }
    498     }
    499 
    500     /**
    501      * Gets the native IMS call session.
    502      * @hide
    503      */
    504     public IImsCallSession getSession() {
    505         return miSession;
    506     }
    507 
    508     /**
    509      * Checks if the session is in call.
    510      *
    511      * @return true if the session is in call
    512      */
    513     public boolean isInCall() {
    514         if (mClosed) {
    515             return false;
    516         }
    517 
    518         try {
    519             return miSession.isInCall();
    520         } catch (RemoteException e) {
    521             return false;
    522         }
    523     }
    524 
    525     /**
    526      * Sets the listener to listen to the session events. A {@link ImsCallSession}
    527      * can only hold one listener at a time. Subsequent calls to this method
    528      * override the previous listener.
    529      *
    530      * @param listener to listen to the session events of this object
    531      */
    532     public void setListener(Listener listener) {
    533         mListener = listener;
    534     }
    535 
    536     /**
    537      * Mutes or unmutes the mic for the active call.
    538      *
    539      * @param muted true if the call is muted, false otherwise
    540      */
    541     public void setMute(boolean muted) {
    542         if (mClosed) {
    543             return;
    544         }
    545 
    546         try {
    547             miSession.setMute(muted);
    548         } catch (RemoteException e) {
    549         }
    550     }
    551 
    552     /**
    553      * Initiates an IMS call with the specified target and call profile.
    554      * The session listener is called back upon defined session events.
    555      * The method is only valid to call when the session state is in
    556      * {@link ImsCallSession#State#IDLE}.
    557      *
    558      * @param callee dialed string to make the call to
    559      * @param profile call profile to make the call with the specified service type,
    560      *      call type and media information
    561      * @see Listener#callSessionStarted, Listener#callSessionStartFailed
    562      */
    563     public void start(String callee, ImsCallProfile profile) {
    564         if (mClosed) {
    565             return;
    566         }
    567 
    568         try {
    569             miSession.start(callee, profile);
    570         } catch (RemoteException e) {
    571         }
    572     }
    573 
    574     /**
    575      * Initiates an IMS conference call with the specified target and call profile.
    576      * The session listener is called back upon defined session events.
    577      * The method is only valid to call when the session state is in
    578      * {@link ImsCallSession#State#IDLE}.
    579      *
    580      * @param participants participant list to initiate an IMS conference call
    581      * @param profile call profile to make the call with the specified service type,
    582      *      call type and media information
    583      * @see Listener#callSessionStarted, Listener#callSessionStartFailed
    584      */
    585     public void start(String[] participants, ImsCallProfile profile) {
    586         if (mClosed) {
    587             return;
    588         }
    589 
    590         try {
    591             miSession.startConference(participants, profile);
    592         } catch (RemoteException e) {
    593         }
    594     }
    595 
    596     /**
    597      * Accepts an incoming call or session update.
    598      *
    599      * @param callType call type specified in {@link ImsCallProfile} to be answered
    600      * @param profile stream media profile {@link ImsStreamMediaProfile} to be answered
    601      * @see Listener#callSessionStarted
    602      */
    603     public void accept(int callType, ImsStreamMediaProfile profile) {
    604         if (mClosed) {
    605             return;
    606         }
    607 
    608         try {
    609             miSession.accept(callType, profile);
    610         } catch (RemoteException e) {
    611         }
    612     }
    613 
    614     /**
    615      * Rejects an incoming call or session update.
    616      *
    617      * @param reason reason code to reject an incoming call
    618      * @see Listener#callSessionStartFailed
    619      */
    620     public void reject(int reason) {
    621         if (mClosed) {
    622             return;
    623         }
    624 
    625         try {
    626             miSession.reject(reason);
    627         } catch (RemoteException e) {
    628         }
    629     }
    630 
    631     /**
    632      * Terminates a call.
    633      *
    634      * @see Listener#callSessionTerminated
    635      */
    636     public void terminate(int reason) {
    637         if (mClosed) {
    638             return;
    639         }
    640 
    641         try {
    642             miSession.terminate(reason);
    643         } catch (RemoteException e) {
    644         }
    645     }
    646 
    647     /**
    648      * Puts a call on hold. When it succeeds, {@link Listener#callSessionHeld} is called.
    649      *
    650      * @param profile stream media profile {@link ImsStreamMediaProfile} to hold the call
    651      * @see Listener#callSessionHeld, Listener#callSessionHoldFailed
    652      */
    653     public void hold(ImsStreamMediaProfile profile) {
    654         if (mClosed) {
    655             return;
    656         }
    657 
    658         try {
    659             miSession.hold(profile);
    660         } catch (RemoteException e) {
    661         }
    662     }
    663 
    664     /**
    665      * Continues a call that's on hold. When it succeeds,
    666      * {@link Listener#callSessionResumed} is called.
    667      *
    668      * @param profile stream media profile {@link ImsStreamMediaProfile} to resume the call
    669      * @see Listener#callSessionResumed, Listener#callSessionResumeFailed
    670      */
    671     public void resume(ImsStreamMediaProfile profile) {
    672         if (mClosed) {
    673             return;
    674         }
    675 
    676         try {
    677             miSession.resume(profile);
    678         } catch (RemoteException e) {
    679         }
    680     }
    681 
    682     /**
    683      * Merges the active & hold call. When it succeeds,
    684      * {@link Listener#callSessionMerged} is called.
    685      *
    686      * @see Listener#callSessionMerged, Listener#callSessionMergeFailed
    687      */
    688     public void merge() {
    689         if (mClosed) {
    690             return;
    691         }
    692 
    693         try {
    694             miSession.merge();
    695         } catch (RemoteException e) {
    696         }
    697     }
    698 
    699     /**
    700      * Updates the current call's properties (ex. call mode change: video upgrade / downgrade).
    701      *
    702      * @param callType call type specified in {@link ImsCallProfile} to be updated
    703      * @param profile stream media profile {@link ImsStreamMediaProfile} to be updated
    704      * @see Listener#callSessionUpdated, Listener#callSessionUpdateFailed
    705      */
    706     public void update(int callType, ImsStreamMediaProfile profile) {
    707         if (mClosed) {
    708             return;
    709         }
    710 
    711         try {
    712             miSession.update(callType, profile);
    713         } catch (RemoteException e) {
    714         }
    715     }
    716 
    717     /**
    718      * Extends this call to the conference call with the specified recipients.
    719      *
    720      * @participants participant list to be invited to the conference call after extending the call
    721      * @see Listener#sessionConferenceExtened, Listener#sessionConferenceExtendFailed
    722      */
    723     public void extendToConference(String[] participants) {
    724         if (mClosed) {
    725             return;
    726         }
    727 
    728         try {
    729             miSession.extendToConference(participants);
    730         } catch (RemoteException e) {
    731         }
    732     }
    733 
    734     /**
    735      * Requests the conference server to invite an additional participants to the conference.
    736      *
    737      * @participants participant list to be invited to the conference call
    738      * @see Listener#sessionInviteParticipantsRequestDelivered,
    739      *      Listener#sessionInviteParticipantsRequestFailed
    740      */
    741     public void inviteParticipants(String[] participants) {
    742         if (mClosed) {
    743             return;
    744         }
    745 
    746         try {
    747             miSession.inviteParticipants(participants);
    748         } catch (RemoteException e) {
    749         }
    750     }
    751 
    752     /**
    753      * Requests the conference server to remove the specified participants from the conference.
    754      *
    755      * @param participants participant list to be removed from the conference call
    756      * @see Listener#sessionRemoveParticipantsRequestDelivered,
    757      *      Listener#sessionRemoveParticipantsRequestFailed
    758      */
    759     public void removeParticipants(String[] participants) {
    760         if (mClosed) {
    761             return;
    762         }
    763 
    764         try {
    765             miSession.removeParticipants(participants);
    766         } catch (RemoteException e) {
    767         }
    768     }
    769 
    770 
    771     /**
    772      * Sends a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833</a>,
    773      * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15,
    774      * and event flash to 16. Currently, event flash is not supported.
    775      *
    776      * @param c the DTMF to send. '0' ~ '9', 'A' ~ 'D', '*', '#' are valid inputs.
    777      */
    778     public void sendDtmf(char c) {
    779         if (mClosed) {
    780             return;
    781         }
    782 
    783         try {
    784             miSession.sendDtmf(c, null);
    785         } catch (RemoteException e) {
    786         }
    787     }
    788 
    789     /**
    790      * Sends an USSD message.
    791      *
    792      * @param ussdMessage USSD message to send
    793      */
    794     public void sendUssd(String ussdMessage) {
    795         if (mClosed) {
    796             return;
    797         }
    798 
    799         try {
    800             miSession.sendUssd(ussdMessage);
    801         } catch (RemoteException e) {
    802         }
    803     }
    804 
    805     /**
    806      * A listener type for receiving notification on IMS call session events.
    807      * When an event is generated for an {@link IImsCallSession},
    808      * the application is notified by having one of the methods called on
    809      * the {@link IImsCallSessionListener}.
    810      */
    811     private class IImsCallSessionListenerProxy extends IImsCallSessionListener.Stub {
    812         /**
    813          * Notifies the result of the basic session operation (setup / terminate).
    814          */
    815         @Override
    816         public void callSessionProgressing(IImsCallSession session,
    817                 ImsStreamMediaProfile profile) {
    818             if (mListener != null) {
    819                 mListener.callSessionProgressing(ImsCallSession.this, profile);
    820             }
    821         }
    822 
    823         @Override
    824         public void callSessionStarted(IImsCallSession session,
    825                 ImsCallProfile profile) {
    826             if (mListener != null) {
    827                 mListener.callSessionStarted(ImsCallSession.this, profile);
    828             }
    829         }
    830 
    831         @Override
    832         public void callSessionStartFailed(IImsCallSession session,
    833                 ImsReasonInfo reasonInfo) {
    834             if (mListener != null) {
    835                 mListener.callSessionStartFailed(ImsCallSession.this, reasonInfo);
    836             }
    837         }
    838 
    839         @Override
    840         public void callSessionTerminated(IImsCallSession session,
    841                 ImsReasonInfo reasonInfo) {
    842             if (mListener != null) {
    843                 mListener.callSessionTerminated(ImsCallSession.this, reasonInfo);
    844             }
    845         }
    846 
    847         /**
    848          * Notifies the result of the call hold/resume operation.
    849          */
    850         @Override
    851         public void callSessionHeld(IImsCallSession session,
    852                 ImsCallProfile profile) {
    853             if (mListener != null) {
    854                 mListener.callSessionHeld(ImsCallSession.this, profile);
    855             }
    856         }
    857 
    858         @Override
    859         public void callSessionHoldFailed(IImsCallSession session,
    860                 ImsReasonInfo reasonInfo) {
    861             if (mListener != null) {
    862                 mListener.callSessionHoldFailed(ImsCallSession.this, reasonInfo);
    863             }
    864         }
    865 
    866         @Override
    867         public void callSessionHoldReceived(IImsCallSession session,
    868                 ImsCallProfile profile) {
    869             if (mListener != null) {
    870                 mListener.callSessionHoldReceived(ImsCallSession.this, profile);
    871             }
    872         }
    873 
    874         @Override
    875         public void callSessionResumed(IImsCallSession session,
    876                 ImsCallProfile profile) {
    877             if (mListener != null) {
    878                 mListener.callSessionResumed(ImsCallSession.this, profile);
    879             }
    880         }
    881 
    882         @Override
    883         public void callSessionResumeFailed(IImsCallSession session,
    884                 ImsReasonInfo reasonInfo) {
    885             if (mListener != null) {
    886                 mListener.callSessionResumeFailed(ImsCallSession.this, reasonInfo);
    887             }
    888         }
    889 
    890         @Override
    891         public void callSessionResumeReceived(IImsCallSession session,
    892                 ImsCallProfile profile) {
    893             if (mListener != null) {
    894                 mListener.callSessionResumeReceived(ImsCallSession.this, profile);
    895             }
    896         }
    897 
    898         /**
    899          * Notifiies the result of call merge operation.
    900          */
    901         @Override
    902         public void callSessionMerged(IImsCallSession session,
    903                 IImsCallSession newSession, ImsCallProfile profile) {
    904             if (mListener != null) {
    905                 mListener.callSessionMerged(ImsCallSession.this,
    906                         new ImsCallSession(newSession), profile);
    907             }
    908         }
    909 
    910         @Override
    911         public void callSessionMergeFailed(IImsCallSession session,
    912                 ImsReasonInfo reasonInfo) {
    913             if (mListener != null) {
    914                 mListener.callSessionMergeFailed(ImsCallSession.this, reasonInfo);
    915             }
    916         }
    917 
    918         /**
    919          * Notifies the result of call upgrade / downgrade or any other call updates.
    920          */
    921         @Override
    922         public void callSessionUpdated(IImsCallSession session,
    923                 ImsCallProfile profile) {
    924             if (mListener != null) {
    925                 mListener.callSessionUpdated(ImsCallSession.this, profile);
    926             }
    927         }
    928 
    929         @Override
    930         public void callSessionUpdateFailed(IImsCallSession session,
    931                 ImsReasonInfo reasonInfo) {
    932             if (mListener != null) {
    933                 mListener.callSessionUpdateFailed(ImsCallSession.this, reasonInfo);
    934             }
    935         }
    936 
    937         @Override
    938         public void callSessionUpdateReceived(IImsCallSession session,
    939                 ImsCallProfile profile) {
    940             if (mListener != null) {
    941                 mListener.callSessionUpdateReceived(ImsCallSession.this, profile);
    942             }
    943         }
    944 
    945         /**
    946          * Notifies the result of conference extension.
    947          */
    948         @Override
    949         public void callSessionConferenceExtended(IImsCallSession session,
    950                 IImsCallSession newSession, ImsCallProfile profile) {
    951             if (mListener != null) {
    952                 mListener.callSessionConferenceExtended(ImsCallSession.this,
    953                         new ImsCallSession(newSession), profile);
    954             }
    955         }
    956 
    957         @Override
    958         public void callSessionConferenceExtendFailed(IImsCallSession session,
    959                 ImsReasonInfo reasonInfo) {
    960             if (mListener != null) {
    961                 mListener.callSessionConferenceExtendFailed(ImsCallSession.this, reasonInfo);
    962             }
    963         }
    964 
    965         @Override
    966         public void callSessionConferenceExtendReceived(IImsCallSession session,
    967                 IImsCallSession newSession, ImsCallProfile profile) {
    968             if (mListener != null) {
    969                 mListener.callSessionConferenceExtendReceived(ImsCallSession.this,
    970                         new ImsCallSession(newSession), profile);
    971             }
    972         }
    973 
    974         /**
    975          * Notifies the result of the participant invitation / removal to/from
    976          * the conference session.
    977          */
    978         @Override
    979         public void callSessionInviteParticipantsRequestDelivered(IImsCallSession session) {
    980             if (mListener != null) {
    981                 mListener.callSessionInviteParticipantsRequestDelivered(ImsCallSession.this);
    982             }
    983         }
    984 
    985         @Override
    986         public void callSessionInviteParticipantsRequestFailed(IImsCallSession session,
    987                 ImsReasonInfo reasonInfo) {
    988             if (mListener != null) {
    989                 mListener.callSessionInviteParticipantsRequestFailed(ImsCallSession.this,
    990                         reasonInfo);
    991             }
    992         }
    993 
    994         @Override
    995         public void callSessionRemoveParticipantsRequestDelivered(IImsCallSession session) {
    996             if (mListener != null) {
    997                 mListener.callSessionRemoveParticipantsRequestDelivered(ImsCallSession.this);
    998             }
    999         }
   1000 
   1001         @Override
   1002         public void callSessionRemoveParticipantsRequestFailed(IImsCallSession session,
   1003                 ImsReasonInfo reasonInfo) {
   1004             if (mListener != null) {
   1005                 mListener.callSessionRemoveParticipantsRequestFailed(ImsCallSession.this,
   1006                         reasonInfo);
   1007             }
   1008         }
   1009 
   1010         /**
   1011          * Notifies the changes of the conference info. in the conference session.
   1012          */
   1013         @Override
   1014         public void callSessionConferenceStateUpdated(IImsCallSession session,
   1015                 ImsConferenceState state) {
   1016             if (mListener != null) {
   1017                 mListener.callSessionConferenceStateUpdated(ImsCallSession.this, state);
   1018             }
   1019         }
   1020 
   1021         /**
   1022          * Notifies the incoming USSD message.
   1023          */
   1024         @Override
   1025         public void callSessionUssdMessageReceived(IImsCallSession session,
   1026                 int mode, String ussdMessage) {
   1027             if (mListener != null) {
   1028                 mListener.callSessionUssdMessageReceived(ImsCallSession.this, mode, ussdMessage);
   1029             }
   1030         }
   1031 
   1032         /**
   1033          * Notifies of handover information for this call
   1034          */
   1035         @Override
   1036         public void callSessionHandover(IImsCallSession session,
   1037                                  int srcAccessTech, int targetAccessTech,
   1038                                  ImsReasonInfo reasonInfo) {
   1039             if (mListener != null) {
   1040                 mListener.callSessionHandover(ImsCallSession.this, srcAccessTech,
   1041                         targetAccessTech, reasonInfo);
   1042             }
   1043         }
   1044 
   1045         @Override
   1046         public void callSessionHandoverFailed(IImsCallSession session,
   1047                                        int srcAccessTech, int targetAccessTech,
   1048                                        ImsReasonInfo reasonInfo) {
   1049             if (mListener != null) {
   1050                 mListener.callSessionHandoverFailed(ImsCallSession.this, srcAccessTech,
   1051                         targetAccessTech, reasonInfo);
   1052             }
   1053         }
   1054     }
   1055 }
   1056