2871052bdcc177cdcbde42b59d9671bf08737646
[android/platform/frameworks/opt/net/ims.git] / src / java / com / android / ims / internal / ImsCallSession.java
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 }