001    package com.skype.api;
002    
003    import java.io.IOException;
004    import java.util.*;
005    import com.skype.ipc.*;
006    /**
007     * Conversation participant class. Instances of this class represent contacts when in the context of conversations. Amongst others, this class has a Ring method for requesting live status with the target contact. This class also holds typing indicator property and access rights for the contact in context of public conversations. <br>
008     */
009    
010    
011    public class Participant extends SkypeObject {
012    
013    
014            public interface ParticipantListener {
015                    /** This event gets called when there are changes to Participant properties defined in Participant.PROPERTY  */
016                    public void OnPropertyChange(SkypeObject obj, PROPERTY prop, Object value);
017                    
018                    /**This event gets fired on receiving a DTMF signal sent by Participant. Note that this event will only fire if the Participant is also using a Skype client. Skype audio library does not monitor incoming voice streams for dial tones. DTMF events are propagated to remote participants via data channel. Incoming DTMF tones transmitted from, for example, mobile phones, will not cause this event to fire. In case of incoming DTMF signals from Skype clients, DTMF tones are also inserted into the audio stream. You don't have to inject those into local audio playback yourself. <br>*/
019                    public void OnIncomingDTMF(SkypeObject obj, DTMF dtmf);
020                    
021            }
022            
023            public Participant(int oid, Skype skype) {
024                    super(oid,skype);
025                    /**get default properties for this module **/
026                    GetDefaultProps();
027            }
028            
029            private static final int MODULE_ID = 19;
030            
031            public static final int moduleID() {
032                    return MODULE_ID;
033            }
034            
035            /** Properties of the Participant class */
036            public enum PROPERTY {
037            
038                    /** [ALL] ID of corresponding conversation. Here and below, [ALL] tag indicates that the property has meaning and is set in context of all participants in the conversation. [OTHERS] tag has meaning only for participants who are not the local user. <br>, type: Conversation */
039                    convo_id(930),
040                    
041                    /** [ALL] skypename OR pstn_number OR namespace:identity, type: String */
042                    identity(931),
043                    
044                    /** [ALL] Participant.RANK, type: RANK */
045                    rank(932),
046                    
047                    /** Not set (should be: requested Participant.RANK, higher than the current one), type: RANK */
048                    requested_rank(933),
049                    
050                    /** [ALL] the typing indicator, type: TEXT_STATUS */
051                    text_status(934),
052                    
053                    /** [ALL] voice status, type: VOICE_STATUS */
054                    voice_status(935),
055                    
056                    /** [ALL] video status, type: VIDEO_STATUS */
057                    video_status(936),
058                    
059                    /** [ALL] identity that was used to establish current live session with that participant (can be different from participant identity), type: String */
060                    live_identity(943),
061                    
062                    /** [OTHERS] 'price_per_minute_float currency' - eg '0.01 EUR'. Note that this property obtains value only after the participant goes into live state. It cannot be used to display call rates before the call starts. <br>, type: String */
063                    live_price_for_me(938),
064                    
065                    /** [OTHERS] list of identities where the live session is being forwarded (if they are disclosed), space separated, type: String */
066                    live_fwd_identities(948),
067                    
068                    /** [ALL] time of joining the live session, type: int */
069                    live_start_timestamp(939),
070                    
071                    /** [ALL] current 'loudness' level when SPEAKING (0..10), type: int */
072                    sound_level(941),
073                    
074                    /** [OTHERS] call (audio and video) debug info, type: String */
075                    debuginfo(942),
076                    
077                    /** [OTHERS], type: String */
078                    last_voice_error(947),
079                    
080                    /** [ALL] space separated tokens values: CPU_INUSE CPU_SLOW CPU_HIGH HIGH_ECHO HIGH_NOISE MUTED_INPUT LOW_INPUT MUTED_INPUT_ACTIVITY FW_STRONG FW_BAD NOT_UDP CALL_BW_LOW RECORD_ERROR + values in video debug info, type: String */
081                    quality_problems(949),
082                    
083                    /** [ALL] participant type during livesession as specified in IDENTITYTYPE, type: contact.IDENTITYTYPE */
084                    live_type(950),
085                    
086                    /** [OTHERS] participant livesession country code - used for emergency calls only atm, type: String */
087                    live_country(951),
088                    
089                    /** [OTHERS] Transferor identity (transferee side) <br>, type: String */
090                    transferred_by(952),
091                    
092                    /** [OTHERS] Identity of recipient of transfer (transferor side, caller side) <br>, type: String */
093                    transferred_to(953),
094                    
095                    /** [ALL] Identity of the user who added this participant to the conversation, type: Sid.String  <br>, type: String */
096                    adder(954);
097                    
098                    private static final Map<Integer,PROPERTY> lookup = new HashMap<Integer,PROPERTY>();
099                    
100                    static {
101                            for(PROPERTY s : EnumSet.allOf(PROPERTY.class))
102                                    lookup.put(s.getId(), s);
103                    }
104                    
105                    private final int id;
106                    
107                    private PROPERTY(int value) {
108                            this.id = value;
109                    }
110                    
111                    public int getId() { return id; }
112                    
113                    public static PROPERTY get(int code) {
114                            return lookup.get(code);
115                    }
116                    
117                    public static PROPERTY fromString(String s) {
118                            for (PROPERTY p : lookup.values()) {
119                                    if (p.toString() == s) {
120                                            return p;
121                                    }
122                            }
123                            return null;
124                    }
125            }
126            
127            public Object GetPropertyAsEnum(int propid) {
128                    return PROPERTY.get(propid);
129            }
130            
131            public String GetStrProperty(PROPERTY prop) {
132                    //check in propcache if so then return
133                    if (mPropCache.containsKey(new Integer(prop.id))){
134                            String value =  (String)mPropCache.get(prop.id);
135                            if (value != null && !(value.length() == 0) ){
136                                    return value;
137                            }
138                    }
139                    //else get from skypekit...
140                    GetPropertyRequest request = new GetPropertyRequest(19, mObjectId, prop.id);
141                    
142                    String string = null;
143                    GetPropertyResponse r = skype.GetProperty(request);
144                    if (r != null){
145                            string = r.GetAsString();
146                    }
147                    
148                    if (string != null)
149                    {
150                            mPropCache.put(new Integer(prop.id), string);
151                    }
152                    return string;
153            }
154            
155            public int GetIntProperty(PROPERTY prop) {
156                    //check in propcache if so then return
157                    if (mPropCache.containsKey(new Integer(prop.id))){
158                            int value = ((Integer)mPropCache.get(prop.id)).intValue();
159                            if (value != 0){
160                                    return value;
161                            }
162                    }
163                    //else get from skypekit...
164                    GetPropertyRequest request = new GetPropertyRequest(moduleID(), mObjectId, prop.id);
165                    
166                    Integer integer = null;
167                    GetPropertyResponse r = skype.GetProperty(request);
168                    if (r != null){
169                            integer  = r.GetAsInt();
170                    }
171                    
172                    if (integer != null)
173                    {
174                            mPropCache.put(new Integer(prop.id), integer);
175                            return integer.intValue();
176                    }
177                    else
178                    {
179                            return 0;
180                    }
181            }
182            
183            public boolean GetBooleanProperty(PROPERTY prop) {
184                    //check in propcache if so then return
185                    if (mPropCache.containsKey(new Integer(prop.id))){
186                            return ((Boolean)mPropCache.get(prop.id)).booleanValue();
187                    }
188                    //else get from skypekit...
189                    GetPropertyRequest request = new GetPropertyRequest(moduleID(), mObjectId, prop.id);
190                    
191                    Boolean boolResp = null;
192                    GetPropertyResponse r = skype.GetProperty(request);
193                    if (r != null){
194                            boolResp  = r.GetAsBoolean();
195                    }
196                    
197                    if (boolResp != null)
198                    {
199                            mPropCache.put(new Integer(prop.id), boolResp);
200                            return boolResp.booleanValue();
201                    }
202                    else
203                    {
204                            return false;
205                    }
206            }
207            
208            public byte [] GetBinProperty(PROPERTY prop) {
209                    //get from skypekit...
210                    GetPropertyRequest request = new GetPropertyRequest(19, mObjectId, prop.id);
211                    
212                    byte [] data = null;
213                    GetPropertyResponse r = skype.GetProperty(request);
214                    if (r != null) {
215                            data = r.GetAsBinary();
216                    }
217                    return data;
218            }
219            
220            /**default array of Participant Properties that get fetched & cached upon class construction*/
221            private static PROPERTY [] defaultProperties = { PROPERTY.convo_id, PROPERTY.rank, PROPERTY.identity, PROPERTY.adder};
222            
223            private void GetDefaultProps() {
224                    MultiGetPropertyRequest request = null;
225                    ArrayList<Integer> proparray = null;
226                            /**Add the single oid into array*/
227                            ArrayList<Integer> oidarray=new ArrayList<Integer>();
228                            oidarray.add(mObjectId);
229                            
230                            /**Add all requested propids into array*/
231                            proparray=new ArrayList<Integer>();
232                            for (PROPERTY defaultProp : defaultProperties) {
233                                    proparray.add(defaultProp.getId());
234                            }
235                            /**Generate the request*/
236                            request = new MultiGetPropertyRequest(moduleID(), oidarray,proparray);
237                            
238                            /** Make Multi Get call*/
239                            GetPropertyResponse r=skype.MultiGetProperty(request);
240                            /**Verify that it is a proper multiresponse*/
241                            if(!r.isMultiresponse())
242                            {
243                                    return;
244                            }
245                            /**update property cache with results*/
246                            mPropCache.putAll(r.GetAsMap(mObjectId, proparray));
247                    }
248                    
249                    /**
250                    Recognized values for the P_RANK property. The P_RANK controls participant's privileges in the conversation. See Participant.CanSetRankTo and Participant.SetRankTo methods. <br> */
251                    public enum RANK {
252                    
253                            /** Creator of the chat. There can be only one participant with this type per conversation. Other participants cannot be promoted to Creator rank. <br>*/
254                            CREATOR(1),
255                            
256                            /** Participant who has administrator privileges <br>*/
257                            ADMIN(2),
258                            
259                            /** Participant who can speak and write <br>*/
260                            SPEAKER(3),
261                            
262                            /** Participant who can write but not speak <br>*/
263                            WRITER(4),
264                            
265                            /** Participant who can read but not write/speak <br>*/
266                            SPECTATOR(5),
267                            
268                            /** Participant who is applying to join the conversation. Member cannot be demoted to applicants once they have been accepted.  <br>*/
269                            APPLICANT(6),
270                            
271                            /** Participant who has eft or has been kicked from the conversation <br>*/
272                            RETIRED(7),
273                            
274                            /** Participant who has been banned from the chat <br>*/
275                            OUTLAW(8);
276                            
277                            private static final Map<Integer,RANK> lookup = new HashMap<Integer,RANK>();
278                            
279                            static {
280                                    for(RANK s : EnumSet.allOf(RANK.class))
281                                            lookup.put(s.getId(), s);
282                            }
283                            
284                            private final int id;
285                            
286                            private RANK(int value) {
287                                    this.id = value;
288                            }
289                            
290                            public int getId() { return id; }
291                            
292                            public static RANK get(int code) {
293                                    return lookup.get(code);
294                            }
295                            
296                            public static RANK fromString(String s) {
297                                    for (RANK p : lookup.values()) {
298                                            if (p.toString() == s) {
299                                                    return p;
300                                            }
301                                    }
302                                    return null;
303                            }
304                    }
305                    
306                    /**
307                    Recognized values for the P_TEXT_STATUS property. The P_TEXT_STATUS property has two uses. Firstly, you can use it to implement typing indicators in your UI, to notify the local user that an incoming chat message from this Participant is imminent.  <br><br>To set the P_TEXT_STATUS value, so that remote client UIs can display the local user's typing indicator in their UI, use Conversation.SetMyTextStatusTo method. <br><br>Transmission of P_TEXT_STATUS updates to remote participants of conversations is controlled via SETUPKEY_DISABLE_CHAT_ACTIVITY_INDICATION setup key. <br><br>Secondly, the TEXT_NA value enables you to detect participants who are running clients with no chat capability. <br> */
308                    public enum TEXT_STATUS {
309                    
310                            /** Fallback state in case the text status is not (yet) deternmined. <br>*/
311                            TEXT_UNKNOWN(0),
312                            
313                            /** Text status is not applicable as the participant is using a Skype client that does not support chat (for example: voice-only USB phones). <br>*/
314                            TEXT_NA(1),
315                            
316                            /** Participant is currently not typing. <br>*/
317                            READING(2),
318                            
319                            /** Participant is currently typing. <br>*/
320                            WRITING(3),
321                            
322                            /** This state should be set when following two conditions are true: <br> - interval between keypresses are less than 20 ms; <br> - at least one of the keys adjacent to current key are pressed down. <br>*/
323                            WRITING_AS_ANGRY(4),
324                            
325                            /** The "Cat on keyboard detection" algorthm in Skype is implemented in the UI level, and as such is not present in the SkypeKit API. Should you wish to implement similar algorthm in your own UI, you can get the basic logic from the PawSense FAQ - http://www.bitboost.com/pawsense/pawsense-faq.html <br>*/
326                            WRITING_AS_CAT(5);
327                            
328                            private static final Map<Integer,TEXT_STATUS> lookup = new HashMap<Integer,TEXT_STATUS>();
329                            
330                            static {
331                                    for(TEXT_STATUS s : EnumSet.allOf(TEXT_STATUS.class))
332                                            lookup.put(s.getId(), s);
333                            }
334                            
335                            private final int id;
336                            
337                            private TEXT_STATUS(int value) {
338                                    this.id = value;
339                            }
340                            
341                            public int getId() { return id; }
342                            
343                            public static TEXT_STATUS get(int code) {
344                                    return lookup.get(code);
345                            }
346                            
347                            public static TEXT_STATUS fromString(String s) {
348                                    for (TEXT_STATUS p : lookup.values()) {
349                                            if (p.toString() == s) {
350                                                    return p;
351                                            }
352                                    }
353                                    return null;
354                            }
355                    }
356                    
357                    /**
358                    Recognized values for the P_VOICE_STATUS property.  <br> */
359                    public enum VOICE_STATUS {
360                    
361                            /** Participant voice status is not (yet) determined. <br>*/
362                            VOICE_UNKNOWN(0),
363                            
364                            /** Participant is using a Skype client with no audio capability. <br>*/
365                            VOICE_NA(1),
366                            
367                            /** Participant is using a Skype client that supports audio. <br>*/
368                            VOICE_AVAILABLE(2),
369                            
370                            /** Participant is in process of joining current live session. This is a transitional state. <br>*/
371                            VOICE_CONNECTING(3),
372                            
373                            /** Participant has been invited to join the live session but has not yet accepted. <br>*/
374                            RINGING(4),
375                            
376                            /** Participant is in process of joining current live session. This is another transitional state. <br>*/
377                            EARLY_MEDIA(5),
378                            
379                            /** Participant has joined the current live session but is currently not transmitting audio. <br>*/
380                            LISTENING(6),
381                            
382                            /** Participant has joined the current live session and is transmitting audio. The UI can either use this state to display appropriate "speaking" notification, or alternatively use Participant.P_SOUND_LEVEL if you want your speaking indicator to also reflect audio volume coming from the Participant. <br>*/
383                            SPEAKING(7),
384                            
385                            /** Participant has joined the current live session but the audio is currently on hold. <br>*/
386                            VOICE_ON_HOLD(8),
387                            
388                            /** Participant will be placed in this state for some seconds after live session has finished. This is another transitional state. <br>*/
389                            VOICE_STOPPED(9);
390                            
391                            private static final Map<Integer,VOICE_STATUS> lookup = new HashMap<Integer,VOICE_STATUS>();
392                            
393                            static {
394                                    for(VOICE_STATUS s : EnumSet.allOf(VOICE_STATUS.class))
395                                            lookup.put(s.getId(), s);
396                            }
397                            
398                            private final int id;
399                            
400                            private VOICE_STATUS(int value) {
401                                    this.id = value;
402                            }
403                            
404                            public int getId() { return id; }
405                            
406                            public static VOICE_STATUS get(int code) {
407                                    return lookup.get(code);
408                            }
409                            
410                            public static VOICE_STATUS fromString(String s) {
411                                    for (VOICE_STATUS p : lookup.values()) {
412                                            if (p.toString() == s) {
413                                                    return p;
414                                            }
415                                    }
416                                    return null;
417                            }
418                    }
419                    
420                    /**
421                    Recognized values for the P_VIDEO_STATUS property. This property applies to Participant's video send capability, not capability to receive video. <br> */
422                    public enum VIDEO_STATUS {
423                    
424                            /** Video status is not (yet) determined. <br>*/
425                            VIDEO_UNKNOWN(0),
426                            
427                            /** Indicates that this Participant does not have video available.. <br>*/
428                            VIDEO_NA(1),
429                            
430                            /** Indicates that video is available for this participant. When the Participant.P_VIDEO_STATUS obtains this state, it is possible to retrieve the Video object, using Participant.GetVideo method. Further operations, such as starting or stopping the video send/receive will then go through the Video object. <br>*/
431                            VIDEO_AVAILABLE(2),
432                            
433                            /** Transitional state indicating that the Participant is attempting to initiate video send. <br>*/
434                            VIDEO_CONNECTING(3),
435                            
436                            /** Indicates that the participant is currently sending video. <br>*/
437                            STREAMING(4),
438                            
439                            /** Indicates that the participant video send is currently paused. <br>*/
440                            VIDEO_ON_HOLD(5);
441                            
442                            private static final Map<Integer,VIDEO_STATUS> lookup = new HashMap<Integer,VIDEO_STATUS>();
443                            
444                            static {
445                                    for(VIDEO_STATUS s : EnumSet.allOf(VIDEO_STATUS.class))
446                                            lookup.put(s.getId(), s);
447                            }
448                            
449                            private final int id;
450                            
451                            private VIDEO_STATUS(int value) {
452                                    this.id = value;
453                            }
454                            
455                            public int getId() { return id; }
456                            
457                            public static VIDEO_STATUS get(int code) {
458                                    return lookup.get(code);
459                            }
460                            
461                            public static VIDEO_STATUS fromString(String s) {
462                                    for (VIDEO_STATUS p : lookup.values()) {
463                                            if (p.toString() == s) {
464                                                    return p;
465                                            }
466                                    }
467                                    return null;
468                            }
469                    }
470                    
471                    /**
472                     */
473                    public enum DTMF {
474                    
475                            /** */
476                            DTMF_0(0),
477                            
478                            /** */
479                            DTMF_1(1),
480                            
481                            /** */
482                            DTMF_2(2),
483                            
484                            /** */
485                            DTMF_3(3),
486                            
487                            /** */
488                            DTMF_4(4),
489                            
490                            /** */
491                            DTMF_5(5),
492                            
493                            /** */
494                            DTMF_6(6),
495                            
496                            /** */
497                            DTMF_7(7),
498                            
499                            /** */
500                            DTMF_8(8),
501                            
502                            /** */
503                            DTMF_9(9),
504                            
505                            /** */
506                            DTMF_STAR(10),
507                            
508                            /** */
509                            DTMF_POUND(11);
510                            
511                            private static final Map<Integer,DTMF> lookup = new HashMap<Integer,DTMF>();
512                            
513                            static {
514                                    for(DTMF s : EnumSet.allOf(DTMF.class))
515                                            lookup.put(s.getId(), s);
516                            }
517                            
518                            private final int id;
519                            
520                            private DTMF(int value) {
521                                    this.id = value;
522                            }
523                            
524                            public int getId() { return id; }
525                            
526                            public static DTMF get(int code) {
527                                    return lookup.get(code);
528                            }
529                            
530                            public static DTMF fromString(String s) {
531                                    for (DTMF p : lookup.values()) {
532                                            if (p.toString() == s) {
533                                                    return p;
534                                            }
535                                    }
536                                    return null;
537                            }
538                    }
539                    
540                    /**
541                     *Checks whether the current user can set this Participant's conversation privileges to the specified RANK. This enables you to gray out or disable in your UI all the unavailable options for Participant.SetRankTo method. <br>
542                     * @param rank Participant.RANK value to check for. <br>
543                     * @return result Returns true if local user can set participant's rank to the value given in rank argument. <br>
544                     */
545                    public boolean CanSetRankTo( RANK rank) {
546                    
547                            Request request = null;
548                            try {
549                                    request = new XCallRequest(19,1);
550                            } catch (IOException e) {
551                                    e.printStackTrace();
552                                    if (skype.errorListener != null)
553                                            skype.errorListener.OnSkypeKitFatalError();
554                            }
555                            request.addParm('O',0,mObjectId);
556                            request.addParm('e',1,rank.getId());
557                            
558                            Response r = skype.XCall((XCallRequest)request);
559                            
560                            if (r.isErrCall())
561                                    return false;
562                                    
563                            boolean result = false;
564                            result = r.GetAsBoolean(1);
565                            return result;
566                    }
567                    
568                    /**
569                     *Sets Participant's conversation privileges to the given RANK <br>
570                     * @param rank Target Participant.RANK value. <br>
571                     */
572                    public void SetRankTo( RANK rank) {
573                    
574                            Request request = null;
575                            try {
576                                    request = new XCallRequest(19,2);
577                            } catch (IOException e) {
578                                    e.printStackTrace();
579                                    if (skype.errorListener != null)
580                                            skype.errorListener.OnSkypeKitFatalError();
581                            }
582                            request.addParm('O',0,mObjectId);
583                            request.addParm('e',1,rank.getId());
584                            
585                            skype.XCall((XCallRequest)request);
586                    }
587                    
588                    /**
589                     *Initiates live conversation attempt with Participant. <br>
590                     * @param identityToUse Ring an alternate identity, such as a PSTN number. <br>
591                     * @param videoCall Enable video. <br>
592                     * @param nrofRedials Unused. <br>
593                     * @param redialPeriod Unused. <br>
594                     * @param autoStartVM Unused. On dialog, if falling on VM, greeting and recording will be automatically started. <br>
595                     * @param origin When call is initiated from web link, must contain the URI that was used
596                     */
597                    public void Ring( String identityToUse, boolean videoCall, int nrofRedials, int redialPeriod, boolean autoStartVM, String origin) {
598                    
599                            Request request = null;
600                            try {
601                                    request = new XCallRequest(19,3);
602                            } catch (IOException e) {
603                                    e.printStackTrace();
604                                    if (skype.errorListener != null)
605                                            skype.errorListener.OnSkypeKitFatalError();
606                            }
607                            request.addParm('O',0,mObjectId);
608                            request.addParm('S',1,identityToUse);
609                            request.addParm('b',2,videoCall);
610                            request.addParm('u',3,nrofRedials);
611                            request.addParm('u',4,redialPeriod);
612                            request.addParm('b',5,autoStartVM);
613                            request.addParm('S',6,origin);
614                            
615                            skype.XCall((XCallRequest)request);
616                    }
617                    
618                    /**
619                     *Rings this participant, using P_LIVE_IDENTITY property if set. <br>
620                     */
621                    public void RingIt() {
622                    
623                            Request request = null;
624                            try {
625                                    request = new XCallRequest(19,8);
626                            } catch (IOException e) {
627                                    e.printStackTrace();
628                                    if (skype.errorListener != null)
629                                            skype.errorListener.OnSkypeKitFatalError();
630                            }
631                            request.addParm('O',0,mObjectId);
632                            
633                            skype.XCall((XCallRequest)request);
634                    }
635                    
636                    /**
637                     *Sets LIVE_IDENTITY property, an alternate identity to use when ringing, such as a PSTN. <br>
638                     * @param identityToUse Empty string will reset it to default, i.e IDENTITY property value <br>
639                     */
640                    public void SetLiveIdentityToUse( String identityToUse) {
641                    
642                            Request request = null;
643                            try {
644                                    request = new XCallRequest(19,7);
645                            } catch (IOException e) {
646                                    e.printStackTrace();
647                                    if (skype.errorListener != null)
648                                            skype.errorListener.OnSkypeKitFatalError();
649                            }
650                            request.addParm('O',0,mObjectId);
651                            request.addParm('S',1,identityToUse);
652                            
653                            skype.XCall((XCallRequest)request);
654                    }
655                    
656                    /**
657                     *Retrieves a reference to the Video object that corresponds to the Participant. It can be either local video - you can check if this participant's name (P_IDENTITY property) matches the name of the currently logged in account (P_SKYPENAME property) or incoming video from a remote participant.  <br><br>Note that for GetVideo to be successful, the video has to be available for that participant. This can be checked for by examining Participant VIDEO_STATUS property - once it becomes VIDEO_AVAILABLE - you can use GetVideo to obtain the Video object. <br>
658                     * @return video Returns reference to a constructed video object. <br>
659                     */
660                    public Video GetVideo() {
661                    
662                            Request request = null;
663                            try {
664                                    request = new XCallRequest(19,4);
665                            } catch (IOException e) {
666                                    e.printStackTrace();
667                                    if (skype.errorListener != null)
668                                            skype.errorListener.OnSkypeKitFatalError();
669                            }
670                            request.addParm('O',0,mObjectId);
671                            
672                            Response r = skype.XCall((XCallRequest)request);
673                            
674                            if (r.isErrCall())
675                                    return null;
676                                    
677                            int oid = 0;
678                            Video video = null;
679                            oid = r.GetOid(1);
680                            if (oid != AbstractDecoder.NULL_VALUE) {
681                                    video = (Video)skype.factory(Video.moduleID(), oid, skype);
682                            }
683                            return video;
684                    }
685                    
686                    /**
687                     *Removes this participant from the current live session. Note that this does not remove the participant from conversation (for this, use Participant.Retire). It only removes participant from live state. <br>
688                     */
689                    public void Hangup() {
690                    
691                            Request request = null;
692                            try {
693                                    request = new XCallRequest(19,5);
694                            } catch (IOException e) {
695                                    e.printStackTrace();
696                                    if (skype.errorListener != null)
697                                            skype.errorListener.OnSkypeKitFatalError();
698                            }
699                            request.addParm('O',0,mObjectId);
700                            
701                            skype.XCall((XCallRequest)request);
702                    }
703                    
704                    /**
705                     *Forcibly removes this participant from conversation. This method is for removing other people from conversations (for example: as administrative punishment for flooding conversation with spam messages). For local user to leave a conversation, use Conversation.RetireFrom instead. <br>
706                     */
707                    public void Retire() {
708                    
709                            Request request = null;
710                            try {
711                                    request = new XCallRequest(19,6);
712                            } catch (IOException e) {
713                                    e.printStackTrace();
714                                    if (skype.errorListener != null)
715                                            skype.errorListener.OnSkypeKitFatalError();
716                            }
717                            request.addParm('O',0,mObjectId);
718                            
719                            skype.XCall((XCallRequest)request);
720                    }
721                    
722            
723            }