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