    001    package com.skype.api;
    002
    003    import java.io.IOException;
    004    import java.util.*;
    005    import com.skype.ipc.*;
    006    /**
    007     * Address book entry. Encapsulates methods like GetType, GetIdentity, GetAvatar, SendAuthRequest, OpenConversation etc. Single contact can have additional phone numbers attached to it (ASSIGNED_PHONE1 .. ASSIGNED_PHONE3). Note that in the context of a conversation, Contacts are represented by Participant objects. Contact member functions all return a Boolean indicating the success (true) or failure (false) of processing the request itself (transport, runtime availability, and so forth)?not the success or failure of its associated functionality. For example, Contact.IsMemberOf returns true if it was able to make a determination, and its result parameter reflects whether this Contact is a member of the target group. Similarly, Contact.IsMemberOf returns false if it was unable to make a determination, and the value of its result parameter is undefined. <br>
    008     */
    009
    010
    011    public class Contact extends SkypeObject {
    012
    013
    014            public interface ContactListener {
    015                    /** This event gets called when there are changes to Contact properties defined in Contact.PROPERTY  */
    016                    public void OnPropertyChange(SkypeObject obj, PROPERTY prop, Object value);
    017
    018            }
    019
    020            public Contact(int oid, Skype skype) {
    021                    super(oid,skype);
    022                    /**get default properties for this module **/
    023                    GetDefaultProps();
    024            }
    025
    026            private static final int MODULE_ID = 2;
    027
    028            public static final int moduleID() {
    029                    return MODULE_ID;
    030            }
    031
    032            /** Properties of the Contact class */
    033            public enum PROPERTY {
    034
    035                    /** type: Contact.TYPE */
    036                    type(202),
    037
    038                    /** defined if it is a SKYPE contact, type: String */
    039                    skypename(4),
    040
    041                    /** type: String */
    042                    pstnnumber(6),
    043
    044                    /** type: String */
    045                    fullname(5),
    046
    047                    /** integer of YYYYMMDD format, type: int */
    048                    birthday(7),
    049
    050                    /** 1-male, 2-female, type: int */
    051                    gender(8),
    052
    053                    /** ISO language code list, space separated, type: String */
    054                    languages(9),
    055
    056                    /** ISO country code, type: String */
    057                    country(10),
    058
    059                    /** type: String */
    060                    province(11),
    061
    062                    /** type: String */
    063                    city(12),
    064
    065                    /** This corresponds to the Account.P_PHONE_HOME property. The value is set by the remote user in Account profile. As Contact property, this is read-only. <br>, type: String */
    066                    phone_home(13),
    067
    068                    /** This corresponds to the Account.P_PHONE_OFFICE property. The value is set by the remote user in Account profile. As Contact property, this is read-only. If the Contact has not populated his Account profile with sufficient phone numbers, the UI should implement locally adding additional phone numbers to Contact P_ASSIGNED_PHONE1 .. P_ASSIGNED_PHONE3 properties (and corresponding labels). See Contact.SetPhoneNumber method for more information. <br>, type: String */
    069                    phone_office(14),
    070
    071                    /** This corresponds to the Account.P_PHONE_MOBILE property. The value is set by the remote user in Account profile. As Contact property, this is read-only. <br>, type: String */
    072                    phone_mobile(15),
    073
    074                    /** will be hashed before advertising/querying, space separated, type: String */
    075                    emails(16),
    076
    077                    /** type: String */
    078                    homepage(17),
    079
    080                    /** arbitrary introductory text, type: String */
    081                    about(18),
    082
    083                    /** Contact avatar pictures are in JPG format. The original size of avatar pictures are in no more than 96 x 96 pixels in size. However, as they can be smaller, scaling the pictures up too much to fit your UI can lead to distorted images. <br>, type: byte[] */
    084                    avatar_image(37),
    085
    086                    /** Personal mood message (visible to authorized users only).  <br>, type: String */
    087                    mood_text(26),
    088
    089                    /** XML version of personal mood text, type: String */
    090                    rich_mood_text(205),
    091
    092                    /** 24*3600+diff_to_UTC_in_seconds. NB! changes with DST <br>, type: int */
    093                    timezone(27),
    094
    095                    /** binary tag that can be queried via Contact.HasCapability(), type: byte[] */
    096                    capabilities(36),
    097
    098                    /** UNIX timestamp of last profile change, type: int */
    099                    profile_timestamp(19),
    100
    101                    /** count of this user's authorized contacts <br>, type: int */
    102                    nrof_authed_buddies(28),
    103
    104                    /** ISO country code assigned by the IP, type: String */
    105                    ipcountry(29),
    106
    107                    /** UNIX timestamp of when current avatar was set, type: int */
    108                    avatar_timestamp(182),
    109
    110                    /** UNIX timestamp of when current mood was set, type: int */
    111                    mood_timestamp(183),
    112
    113                    /** set if the contact is waiting to be authorized. The value contains auth. request text <br>, type: String */
    114                    received_authrequest(20),
    115
    116                    /** timestamp of last received auth-request, type: int */
    117                    authreq_timestamp(25),
    118
    119                    /** X timestamp of last successful ping to that user, type: int */
    120                    lastonline_timestamp(35),
    121
    122                    /** Contact.AVAILABILITY, type: AVAILABILITY */
    123                    availability(34),
    124
    125                    /** always set (assigned by lib by looking at various fields), type: String */
    126                    displayname(21),
    127
    128                    /** true if querying additional information from p2p or server <br>, type: boolean */
    129                    refreshing(22),
    130
    131                    /** Contact.AUTHLEVEL, change via Contact.GiveAuthlevel(), type: AUTHLEVEL */
    132                    given_authlevel(23),
    133
    134                    /** change via Contact.GiveDisplayname(), type: String */
    135                    given_displayname(33),
    136
    137                    /** change via Contact.AssignComment(), type: String */
    138                    assigned_comment(180),
    139
    140                    /** UNIX timestamp of last outbound session (call, chat, FT, etc), type: int */
    141                    lastused_timestamp(39),
    142
    143                    /** for contacts that have CONTACT_RECEIVED_AUTHREQUEST, how many times in a row they have requested it without positive answer, type: int */
    144                    authrequest_count(41),
    145
    146                    /** Office phone no. of the contact. This property should NOT be used for SkypeOut contacts <br>, type: String */
    147                    assigned_phone1(184),
    148
    149                    /** Value "1" in this property will be translated as "Office" by Skype Windows desktop client, according to UI language settings <br>, type: String */
    150                    assigned_phone1_label(185),
    151
    152                    /** Mobile phone no. of the contact <br>, type: String */
    153                    assigned_phone2(186),
    154
    155                    /** Value "2" in this property will be translated as "Mobile" by Skype Windows desktop client, according to UI language settings <br>, type: String */
    156                    assigned_phone2_label(187),
    157
    158                    /** "Other phone no. of the contact, type: String */
    159                    assigned_phone3(188),
    160
    161                    /** Value "3" in this property will be translated as "Other" by Skype Windows desktop client, according to UI language settings <br>, type: String */
    162                    assigned_phone3_label(189),
    163
    164                    /** Contact's order by presence popularity <br>, type: int */
    165                    popularity_ord(42);
    166
    167                    private static final Map<Integer,PROPERTY> lookup = new HashMap<Integer,PROPERTY>();
    168
    169                    static {
    170                            for(PROPERTY s : EnumSet.allOf(PROPERTY.class))
    171                                    lookup.put(s.getId(), s);
    172                    }
    173
    174                    private final int id;
    175
    176                    private PROPERTY(int value) {
    177                            this.id = value;
    178                    }
    179
    180                    public int getId() { return id; }
    181
    182                    public static PROPERTY get(int code) {
    183                            return lookup.get(code);
    184                    }
    185
    186                    public static PROPERTY fromString(String s) {
    187                            for (PROPERTY p : lookup.values()) {
    188                                    if (p.toString() == s) {
    189                                            return p;
    190                                    }
    191                            }
    192                            return null;
    193                    }
    194            }
    195
    196            public Object GetPropertyAsEnum(int propid) {
    197                    return PROPERTY.get(propid);
    198            }
    199
    200            public String GetStrProperty(PROPERTY prop) {
    201                    //check in propcache if so then return
    202                    if (mPropCache.containsKey(new Integer(prop.id))){
    203                            String value =  (String)mPropCache.get(prop.id);
    204                            if (value != null && !(value.length() == 0) ){
    205                                    return value;
    206                            }
    207                    }
    208                    //else get from skypekit...
    209                    GetPropertyRequest request = new GetPropertyRequest(2, mObjectId, prop.id);
    210
    211                    String string = null;
    212                    GetPropertyResponse r = skype.GetProperty(request);
    213                    if (r != null){
    214                            string = r.GetAsString();
    215                    }
    216
    217                    if (string != null)
    218                    {
    219                            mPropCache.put(new Integer(prop.id), string);
    220                    }
    221                    return string;
    222            }
    223
    224            public int GetIntProperty(PROPERTY prop) {
    225                    //check in propcache if so then return
    226                    if (mPropCache.containsKey(new Integer(prop.id))){
    227                            int value = ((Integer)mPropCache.get(prop.id)).intValue();
    228                            if (value != 0){
    229                                    return value;
    230                            }
    231                    }
    232                    //else get from skypekit...
    233                    GetPropertyRequest request = new GetPropertyRequest(moduleID(), mObjectId, prop.id);
    234
    235                    Integer integer = null;
    236                    GetPropertyResponse r = skype.GetProperty(request);
    237                    if (r != null){
    238                            integer  = r.GetAsInt();
    239                    }
    240
    241                    if (integer != null)
    242                    {
    243                            mPropCache.put(new Integer(prop.id), integer);
    244                            return integer.intValue();
    245                    }
    246                    else
    247                    {
    248                            return 0;
    249                    }
    250            }
    251
    252            public boolean GetBooleanProperty(PROPERTY prop) {
    253                    //check in propcache if so then return
    254                    if (mPropCache.containsKey(new Integer(prop.id))){
    255                            return ((Boolean)mPropCache.get(prop.id)).booleanValue();
    256                    }
    257                    //else get from skypekit...
    258                    GetPropertyRequest request = new GetPropertyRequest(moduleID(), mObjectId, prop.id);
    259
    260                    Boolean boolResp = null;
    261                    GetPropertyResponse r = skype.GetProperty(request);
    262                    if (r != null){
    263                            boolResp  = r.GetAsBoolean();
    264                    }
    265
    266                    if (boolResp != null)
    267                    {
    268                            mPropCache.put(new Integer(prop.id), boolResp);
    269                            return boolResp.booleanValue();
    270                    }
    271                    else
    272                    {
    273                            return false;
    274                    }
    275            }
    276
    277            public byte [] GetBinProperty(PROPERTY prop) {
    278                    //get from skypekit...
    279                    GetPropertyRequest request = new GetPropertyRequest(2, mObjectId, prop.id);
    280
    281                    byte [] data = null;
    282                    GetPropertyResponse r = skype.GetProperty(request);
    283                    if (r != null) {
    284                            data = r.GetAsBinary();
    285                    }
    286                    return data;
    287            }
    288
    289            /**default array of Contact Properties that get fetched & cached upon class construction*/
    290            private static PROPERTY [] defaultProperties = { PROPERTY.type, PROPERTY.skypename, PROPERTY.fullname, PROPERTY.displayname, PROPERTY.mood_text, PROPERTY.pstnnumber, PROPERTY.availability, PROPERTY.given_displayname};
    291
    292            private void GetDefaultProps() {
    293                    MultiGetPropertyRequest request = null;
    294                    ArrayList<Integer> proparray = null;
    295                            /**Add the single oid into array*/
    296                            ArrayList<Integer> oidarray=new ArrayList<Integer>();
    297                            oidarray.add(mObjectId);
    298
    299                            /**Add all requested propids into array*/
    300                            proparray=new ArrayList<Integer>();
    301                            for (PROPERTY defaultProp : defaultProperties) {
    302                                    proparray.add(defaultProp.getId());
    303                            }
    304                            /**Generate the request*/
    305                            request = new MultiGetPropertyRequest(moduleID(), oidarray,proparray);
    306
    307                            /** Make Multi Get call*/
    308                            GetPropertyResponse r=skype.MultiGetProperty(request);
    309                            /**Verify that it is a proper multiresponse*/
    310                            if(!r.isMultiresponse())
    311                            {
    312                                    return;
    313                            }
    314                            /**update property cache with results*/
    315                            mPropCache.putAll(r.GetAsMap(mObjectId, proparray));
    316                    }
    317
    318                    /**
    319                    Same as with CAPABILITY, enumerator is used by both Contact and Account objects. <br> */
    320                    public enum TYPE {
    321
    322                            /** Contact/account has no pre-identified type. This type is reported by default for SkypeKit clients. <br>*/
    323                            UNRECOGNIZED(0),
    324
    325                            /** Normal Skype contact. <br>*/
    326                            SKYPE(1),
    327
    328                            /** Normal PSTN contact. <br>*/
    329                            PSTN(2),
    330
    331                            /** Emergency number (i.e. 911). <br>*/
    332                            EMERGENCY_PSTN(3),
    333
    334                            /** */
    335                            FREE_PSTN(4),
    336
    337                            /** Undisclosed PSTN number. <br>*/
    338                            UNDISCLOSED_PSTN(5),
    339
    340                            /** This type is currently used by Windows desktop clients for contacts imported from Outlook. <br>*/
    341                            EXTERNAL(6);
    342
    343                            private static final Map<Integer,TYPE> lookup = new HashMap<Integer,TYPE>();
    344
    345                            static {
    346                                    for(TYPE s : EnumSet.allOf(TYPE.class))
    347                                            lookup.put(s.getId(), s);
    348                            }
    349
    350                            private final int id;
    351
    352                            private TYPE(int value) {
    353                                    this.id = value;
    354                            }
    355
    356                            public int getId() { return id; }
    357
    358                            public static TYPE get(int code) {
    359                                    return lookup.get(code);
    360                            }
    361
    362                            public static TYPE fromString(String s) {
    363                                    for (TYPE p : lookup.values()) {
    364                                            if (p.toString() == s) {
    365                                                    return p;
    366                                            }
    367                                    }
    368                                    return null;
    369                            }
    370                    }
    371
    372                    /**
    373                     *Getter method for the TYPE property. <br>
    374                     * @return type
    375                     */
    376                    public TYPE GetType() {
    377
    378                            Request request = null;
    379                            try {
    380                                    request = new XCallRequest(2,1);
    381                            } catch (IOException e) {
    382                                    e.printStackTrace();
    383                                    if (skype.errorListener != null)
    384                                            skype.errorListener.OnSkypeKitFatalError();
    385                            }
    386                            request.addParm('O',0,mObjectId);
    387
    388                            Response r = skype.XCall((XCallRequest)request);
    389
    390                            if (r.isErrCall())
    391                                    return null;
    392
    393                            TYPE type = null;
    394                            type = TYPE.get(r.GetAsInt(1));
    395                            return type;
    396                    }
    397
    398                    /**
    399                    Describes the recognized relational states between a local account and a remote contact. <br> */
    400                    public enum AUTHLEVEL {
    401
    402                            /** Authorization request is either ignored or pending. In this state several functionalities may be blocked, depending on settings. For example, accounts may only allow seeing online presence to be viewable or only receive calls from authorized contacts. <br>*/
    403                            NONE(0),
    404
    405                            /** Contact has been authorized by the local account. <br>*/
    406                            AUTHORIZED_BY_ME(1),
    407
    408                            /** Contact has been blocked by the local account. This prevents incoming calls, chat messages, additional authorization requests etc. <br>*/
    409                            BLOCKED_BY_ME(2);
    410
    411                            private static final Map<Integer,AUTHLEVEL> lookup = new HashMap<Integer,AUTHLEVEL>();
    412
    413                            static {
    414                                    for(AUTHLEVEL s : EnumSet.allOf(AUTHLEVEL.class))
    415                                            lookup.put(s.getId(), s);
    416                            }
    417
    418                            private final int id;
    419
    420                            private AUTHLEVEL(int value) {
    421                                    this.id = value;
    422                            }
    423
    424                            public int getId() { return id; }
    425
    426                            public static AUTHLEVEL get(int code) {
    427                                    return lookup.get(code);
    428                            }
    429
    430                            public static AUTHLEVEL fromString(String s) {
    431                                    for (AUTHLEVEL p : lookup.values()) {
    432                                            if (p.toString() == s) {
    433                                                    return p;
    434                                            }
    435                                    }
    436                                    return null;
    437                            }
    438                    }
    439
    440                    /**
    441                    Describes the superset list of possible Account and Contact online statuses. In case of Account they apply to local user, in case of Contact they apply to remote contacts. <br> */
    442                    public enum AVAILABILITY {
    443
    444                            /** Contact online status cannot be determined. This availability state should not normally reach the SkypeKit UI level. <br>*/
    445                            UNKNOWN(0),
    446
    447                            /** Seeing Contact online status is blocked because authorization between contact and local account has not taken place. <br>*/
    448                            PENDINGAUTH(8),
    449
    450                            /** Remote contact has been blocked by local account. This applies to online accounts. <br>*/
    451                            BLOCKED(9),
    452
    453                            /** Remote SkypeOut contact has been blocked by local account. <br>*/
    454                            BLOCKED_SKYPEOUT(11),
    455
    456                            /** Contact does not have an online status because he is a PSTN contact. <br>*/
    457                            SKYPEOUT(10),
    458
    459                            /** Contact appears to be offline. <br>*/
    460                            OFFLINE(1),
    461
    462                            /** Contact appears to be offline but has voicemail enabled. <br>*/
    463                            OFFLINE_BUT_VM_ABLE(12),
    464
    465                            /** Contact appears to be offline but has enabled call forwarding, so calls may actually get through to him. <br>*/
    466                            OFFLINE_BUT_CF_ABLE(13),
    467
    468                            /** Contact / Account is online <br>*/
    469                            ONLINE(2),
    470
    471                            /** Contact / Account is online but away from keyboard. This can be either turned on manually or by automatic timer. In Windows desktop client, the timer can be configured with minute precision. <br>*/
    472                            AWAY(3),
    473
    474                            /** This online status is marked as deprecated. If a remote contact indicates its status as NOT_AVAILABLE, the UI should handle this as equivalent of AWAY status. <br>*/
    475                            NOT_AVAILABLE(4),
    476
    477                            /** Contact / Account is online but does not wish to be disturbed. This status supersedes AWAY status when the account is DO_NOT_DISTURB the AWAY timer should not modify the status. <br>*/
    478                            DO_NOT_DISTURB(5),
    479
    480                            /** This online status is marked as deprecated. If a remote contact indicates its status as SKYPE_ME, the UI should handle this as equivalent of ONLINE status. <br>*/
    481                            SKYPE_ME(7),
    482
    483                            /** Account status is set to INVISIBLE. This status in not applicable to remote Contacts. When the remote contact has set his availability to INVISIBLE, he will appear as OFFLINE to others. <br>*/
    484                            INVISIBLE(6),
    485
    486                            /** only possible for local user/account*/
    487                            CONNECTING(14),
    488
    489                            /** */
    490                            ONLINE_FROM_MOBILE(15),
    491
    492                            /** *_FROM_MOBILE only possible for remote user*/
    493                            AWAY_FROM_MOBILE(16),
    494
    495                            /** */
    496                            NOT_AVAILABLE_FROM_MOBILE(17),
    497
    498                            /** */
    499                            DO_NOT_DISTURB_FROM_MOBILE(18),
    500
    501                            /** */
    502                            SKYPE_ME_FROM_MOBILE(20);
    503
    504                            private static final Map<Integer,AVAILABILITY> lookup = new HashMap<Integer,AVAILABILITY>();
    505
    506                            static {
    507                                    for(AVAILABILITY s : EnumSet.allOf(AVAILABILITY.class))
    508                                            lookup.put(s.getId(), s);
    509                            }
    510
    511                            private final int id;
    512
    513                            private AVAILABILITY(int value) {
    514                                    this.id = value;
    515                            }
    516
    517                            public int getId() { return id; }
    518
    519                            public static AVAILABILITY get(int code) {
    520                                    return lookup.get(code);
    521                            }
    522
    523                            public static AVAILABILITY fromString(String s) {
    524                                    for (AVAILABILITY p : lookup.values()) {
    525                                            if (p.toString() == s) {
    526                                                    return p;
    527                                            }
    528                                    }
    529                                    return null;
    530                            }
    531                    }
    532
    533                    /**
    534                     * @return identity returns CONTACT_SKYPENAME or CONTACT_PSTNNUMBER value
    535                     */
    536                    public String GetIdentity() {
    537
    538                            Request request = null;
    539                            try {
    540                                    request = new XCallRequest(2,2);
    541                            } catch (IOException e) {
    542                                    e.printStackTrace();
    543                                    if (skype.errorListener != null)
    544                                            skype.errorListener.OnSkypeKitFatalError();
    545                            }
    546                            request.addParm('O',0,mObjectId);
    547
    548                            Response r = skype.XCall((XCallRequest)request);
    549
    550                            if (r.isErrCall())
    551                                    return null;
    552
    553                            String identity = null;
    554                            identity = r.GetAsString(1);
    555                            return identity;
    556                    }
    557
    558                    /**
    559                     *Returns Conrtact's avatar image (JPG). <br>
    560                     * @return GetAvatarResult
    561                     */
    562                    public GetAvatarResult GetAvatar() {
    563
    564                            Request request = null;
    565                            try {
    566                                    request = new XCallRequest(2,4);
    567                            } catch (IOException e) {
    568                                    e.printStackTrace();
    569                                    if (skype.errorListener != null)
    570                                            skype.errorListener.OnSkypeKitFatalError();
    571                            }
    572                            request.addParm('O',0,mObjectId);
    573
    574                            Response r = skype.XCall((XCallRequest)request);
    575
    576                            if (r.isErrCall())
    577                                    return null;
    578
    579                            GetAvatarResult result = new GetAvatarResult();
    580
    581                            boolean present = false;
    582                            present = r.GetAsBoolean(1);
    583                            result.present = present;
    584
    585                            byte[] avatar = null;
    586                            avatar = r.GetAsBinary(2);
    587                            result.avatar = avatar;
    588
    589                            return result;
    590                    }
    591
    592                    public class GetAvatarResult {
    593                            public boolean present; /** <br> - true: the Contact has a custom avatar image <br> - false: the Contact does not have a custom avatar image <br> */
    594                            public byte[] avatar; /** The avatar image data (JPG). If present is false, this will be the Skype-assigned default avatar <br> */
    595                    }
    596
    597                    /**
    598                     *returns verified-by-Skype e-mail for this contact if exists and verifiable
    599                     * @return email
    600                     */
    601                    public String GetVerifiedEmail() {
    602
    603                            Request request = null;
    604                            try {
    605                                    request = new XCallRequest(2,3);
    606                            } catch (IOException e) {
    607                                    e.printStackTrace();
    608                                    if (skype.errorListener != null)
    609                                            skype.errorListener.OnSkypeKitFatalError();
    610                            }
    611                            request.addParm('O',0,mObjectId);
    612
    613                            Response r = skype.XCall((XCallRequest)request);
    614
    615                            if (r.isErrCall())
    616                                    return null;
    617
    618                            String email = null;
    619                            email = r.GetAsString(1);
    620                            return email;
    621                    }
    622
    623                    /**
    624                     *returns verified-by-Skype company for this contact if exists and verifiable
    625                     * @return company
    626                     */
    627                    public String GetVerifiedCompany() {
    628
    629                            Request request = null;
    630                            try {
    631                                    request = new XCallRequest(2,8);
    632                            } catch (IOException e) {
    633                                    e.printStackTrace();
    634                                    if (skype.errorListener != null)
    635                                            skype.errorListener.OnSkypeKitFatalError();
    636                            }
    637                            request.addParm('O',0,mObjectId);
    638
    639                            Response r = skype.XCall((XCallRequest)request);
    640
    641                            if (r.isErrCall())
    642                                    return null;
    643
    644                            String company = null;
    645                            company = r.GetAsString(1);
    646                            return company;
    647                    }
    648
    649                    /**
    650                     *Checks whether the contact is member of a contact group given in group reference argument. <br>
    651                     * @param group The target contact group <br>
    652                     * @return result <br> - true: the Contact is a member of the target contact group <br> - false: the Contact is not a member of the target contact group <br>
    653                     */
    654                    public boolean IsMemberOf( ContactGroup group) {
    655
    656                            Request request = null;
    657                            try {
    658                                    request = new XCallRequest(2,6);
    659                            } catch (IOException e) {
    660                                    e.printStackTrace();
    661                                    if (skype.errorListener != null)
    662                                            skype.errorListener.OnSkypeKitFatalError();
    663                            }
    664                            request.addParm('O',0,mObjectId);
    665                            request.addParm('O',1,group.getOid());
    666
    667                            Response r = skype.XCall((XCallRequest)request);
    668
    669                            if (r.isErrCall())
    670                                    return false;
    671
    672                            boolean result = false;
    673                            result = r.GetAsBoolean(1);
    674                            return result;
    675                    }
    676
    677                    /**
    678                     *Checks whether the contact is member of a pre-defined contact group given in the TYPE argument (type for this property comes from the ContactGroup class). <br>
    679                     * @param groupType The type designator of the target pre-defined contact group. For example, specify this parameter as ContactGroup.TYPE.RECENTLY_CONTACTED_CONTACTS to determine if you've had a recent conversation with this Contact. <br>
    680                     * @return result <br> - true: the Contact is a member of the target contact group <br> - false: the Contact is not a member of the target contact group <br>
    681                     */
    682                    public boolean IsMemberOfHardwiredGroup( ContactGroup.TYPE groupType) {
    683
    684                            Request request = null;
    685                            try {
    686                                    request = new XCallRequest(2,7);
    687                            } catch (IOException e) {
    688                                    e.printStackTrace();
    689                                    if (skype.errorListener != null)
    690                                            skype.errorListener.OnSkypeKitFatalError();
    691                            }
    692                            request.addParm('O',0,mObjectId);
    693                            request.addParm('e',1,groupType.getId());
    694
    695                            Response r = skype.XCall((XCallRequest)request);
    696
    697                            if (r.isErrCall())
    698                                    return false;
    699
    700                            boolean result = false;
    701                            result = r.GetAsBoolean(1);
    702                            return result;
    703                    }
    704
    705                    /**
    706                     *Blocks or unblocks any further incoming communication attempts from this contact. <br>
    707                     * @param blocked <br> - true: block this contact <br> - false: unblock this contact <br>
    708                     * @param abuse Optional parameter to report abuse by this Skype user when blocking this Contact. Note that you can specifiy this parameter as true only when blocking a Contact. Defaults to false if omitted. <br>
    709                     */
    710                    public void SetBlocked( boolean blocked, boolean abuse) {
    711
    712                            Request request = null;
    713                            try {
    714                                    request = new XCallRequest(2,22);
    715                            } catch (IOException e) {
    716                                    e.printStackTrace();
    717                                    if (skype.errorListener != null)
    718                                            skype.errorListener.OnSkypeKitFatalError();
    719                            }
    720                            request.addParm('O',0,mObjectId);
    721                            request.addParm('b',1,blocked);
    722                            request.addParm('b',2,abuse);
    723
    724                            skype.XCall((XCallRequest)request);
    725                    }
    726
    727                    /**
    728                     *Rejects and removes a pending authorization request from this Contact. <br>
    729                     */
    730                    public void IgnoreAuthRequest() {
    731
    732                            Request request = null;
    733                            try {
    734                                    request = new XCallRequest(2,21);
    735                            } catch (IOException e) {
    736                                    e.printStackTrace();
    737                                    if (skype.errorListener != null)
    738                                            skype.errorListener.OnSkypeKitFatalError();
    739                            }
    740                            request.addParm('O',0,mObjectId);
    741
    742                            skype.XCall((XCallRequest)request);
    743                    }
    744
    745                    /**
    746                     *sets CONTACT_GIVEN_DISPLAYNAME. clears if size(name)==0
    747                     * @param name
    748                     */
    749                    public void GiveDisplayName( String name) {
    750
    751                            Request request = null;
    752                            try {
    753                                    request = new XCallRequest(2,10);
    754                            } catch (IOException e) {
    755                                    e.printStackTrace();
    756                                    if (skype.errorListener != null)
    757                                            skype.errorListener.OnSkypeKitFatalError();
    758                            }
    759                            request.addParm('O',0,mObjectId);
    760                            request.addParm('S',1,name);
    761
    762                            skype.XCall((XCallRequest)request);
    763                    }
    764
    765                    /**
    766                     *Adds or removes this Contact from the ALL_BUDDIES hardwired group. <br>
    767                     * @param isMyBuddy <br> - true: add this contact to the ALL_BUDDIES group <br> - false: delete contact from the ALL_BUDDIES group <br>
    768                     * @param syncAuth This argument is deprecated and should not be used. <br>
    769                     */
    770                    public void SetBuddyStatus( boolean isMyBuddy, boolean syncAuth) {
    771
    772                            Request request = null;
    773                            try {
    774                                    request = new XCallRequest(2,12);
    775                            } catch (IOException e) {
    776                                    e.printStackTrace();
    777                                    if (skype.errorListener != null)
    778                                            skype.errorListener.OnSkypeKitFatalError();
    779                            }
    780                            request.addParm('O',0,mObjectId);
    781                            request.addParm('b',1,isMyBuddy);
    782                            request.addParm('b',2,syncAuth);
    783
    784                            skype.XCall((XCallRequest)request);
    785                    }
    786
    787                    /**
    788                     */
    789                    public enum EXTRA_AUTHREQ_FIELDS {
    790
    791                            /** send verified e-mail blob with this auth request*/
    792                            SEND_VERIFIED_EMAIL(1),
    793
    794                            /** send verified company blob with this auth request*/
    795                            SEND_VERIFIED_COMPANY(2);
    796
    797                            private static final Map<Integer,EXTRA_AUTHREQ_FIELDS> lookup = new HashMap<Integer,EXTRA_AUTHREQ_FIELDS>();
    798
    799                            static {
    800                                    for(EXTRA_AUTHREQ_FIELDS s : EnumSet.allOf(EXTRA_AUTHREQ_FIELDS.class))
    801                                            lookup.put(s.getId(), s);
    802                            }
    803
    804                            private final int id;
    805
    806                            private EXTRA_AUTHREQ_FIELDS(int value) {
    807                                    this.id = value;
    808                            }
    809
    810                            public int getId() { return id; }
    811
    812                            public static EXTRA_AUTHREQ_FIELDS get(int code) {
    813                                    return lookup.get(code);
    814                            }
    815
    816                            public static EXTRA_AUTHREQ_FIELDS fromString(String s) {
    817                                    for (EXTRA_AUTHREQ_FIELDS p : lookup.values()) {
    818                                            if (p.toString() == s) {
    819                                                    return p;
    820                                            }
    821                                    }
    822                                    return null;
    823                            }
    824                    }
    825
    826                    /**
    827                     *Sends a contact authorization request to this user. <br>
    828                     * @param message Text that typically introduces the requesting user and details the reason for the authorization request. This text will be set as Message.P_BODY_XML property of the notification Message the remote user will receive upon getting the authortization request. While this can be the empty string, it cannot be null. <br>
    829                     * @param extras_bitmask Indicates additional information to include with this authorization request: <br> - 0 (zero): do not include any additional information <br> - SEND_VERIFIED_EMAIL: include the requestor's verified e-mail address <br> - SEND_VERIFIED_COMPANY: include verified information regarding the requestor's company <br> - SEND_VERIFIED_EMAIL + SEND_VERIFIED_COMPANY: include both e-mail and company information <br>
    830                     */
    831                    public void SendAuthRequest( String message, int extras_bitmask) {
    832
    833                            Request request = null;
    834                            try {
    835                                    request = new XCallRequest(2,13);
    836                            } catch (IOException e) {
    837                                    e.printStackTrace();
    838                                    if (skype.errorListener != null)
    839                                            skype.errorListener.OnSkypeKitFatalError();
    840                            }
    841                            request.addParm('O',0,mObjectId);
    842                            request.addParm('S',1,message);
    843                            request.addParm('u',2,extras_bitmask);
    844
    845                            skype.XCall((XCallRequest)request);
    846                    }
    847
    848                    /**
    849                     *the contact has accepted my auth request
    850                     * @return result
    851                     */
    852                    public boolean HasAuthorizedMe() {
    853
    854                            Request request = null;
    855                            try {
    856                                    request = new XCallRequest(2,14);
    857                            } catch (IOException e) {
    858                                    e.printStackTrace();
    859                                    if (skype.errorListener != null)
    860                                            skype.errorListener.OnSkypeKitFatalError();
    861                            }
    862                            request.addParm('O',0,mObjectId);
    863
    864                            Response r = skype.XCall((XCallRequest)request);
    865
    866                            if (r.isErrCall())
    867                                    return false;
    868
    869                            boolean result = false;
    870                            result = r.GetAsBoolean(1);
    871                            return result;
    872                    }
    873
    874                    /**
    875                     *Sets the three P_ASSIGNED_PHONEx and P_ASSIGNED_PHONEx_LABEL properties, where x reflects the value of num.  <br><br>The Skype Windows desktop client uses the following conventions when interpreting and assigning values to these properties. While your solution can assign arbitrary values to these properties, we strongly recommend using these conventions to ensure interoperability with the Skype Windows desktop client. Keep in mind that the "number" of these property pairs has no relationship to how the Skype Windows client interprets their label property value strings. For example, the Skype Windows client will interpret P_ASSIGNED_PHONE3_LABEL as "Home" if its value is the string "0".  <br><br>Label strings: <br><br>Populate the label properties with string representations of the numbers "0" through "3", rather than descriptive strings like "Home", "Mobile", and so forth. The Skype desktop clients interpret the numeric string values as: <br> - "0" (zero) - "Home" <br> - "1" (one) - "Office" <br> - "2" - "Mobile" <br> - "3" - "Other" <br><br>Keep in mind that the "number" of a property pair has no relationship to its label string. For example, the Skype Windows client will interpret P_ASSIGNED_PHONE3_LABEL as "Home" if its value is the string "0". <br><br>Phone number strings: <br><br>The Skype Windows desktop client has distinct conventions for Skype Contacts and PSTN (SkypeOut) Contacts: any or all of the property pairs can be used for Skype Contacts; P_ASSIGNED_PHONE1 cannot be used for PSTN Contacts and P_ASSIGNED_PHONE1_LABEL has special meaning for PSTN Contacts. <br>Specifically, the Skype desktop clients use P_ASSIGNED_PHONE1_LABEL as the label for a PSTN Contact's primary number (regardless of whether it's home, mobile, or office), and use P_PSTNNUMBER to hold the actual number. <br><br>
    876                     * @param num The property pair being set, which must be in the range 0..3 <br>
    877                     * @param label The label text for the property being set <br>
    878                     * @param number The phone number for the property being set <br>
    879                     */
    880                    public void SetPhoneNumber( int num, String label, String number) {
    881
    882                            Request request = null;
    883                            try {
    884                                    request = new XCallRequest(2,15);
    885                            } catch (IOException e) {
    886                                    e.printStackTrace();
    887                                    if (skype.errorListener != null)
    888                                            skype.errorListener.OnSkypeKitFatalError();
    889                            }
    890                            request.addParm('O',0,mObjectId);
    891                            request.addParm('u',1,num);
    892                            request.addParm('S',2,label);
    893                            request.addParm('S',3,number);
    894
    895                            skype.XCall((XCallRequest)request);
    896                    }
    897
    898                    /**
    899                     *Retrieves a dialog conversation with the Contact. <br>
    900                     * @return conversation Retrieved dialog. <br>
    901                     */
    902                    public Conversation OpenConversation() {
    903
    904                            Request request = null;
    905                            try {
    906                                    request = new XCallRequest(2,17);
    907                            } catch (IOException e) {
    908                                    e.printStackTrace();
    909                                    if (skype.errorListener != null)
    910                                            skype.errorListener.OnSkypeKitFatalError();
    911                            }
    912                            request.addParm('O',0,mObjectId);
    913
    914                            Response r = skype.XCall((XCallRequest)request);
    915
    916                            if (r.isErrCall())
    917                                    return null;
    918
    919                            int oid = 0;
    920                            Conversation conversation = null;
    921                            oid = r.GetOid(1);
    922                            if (oid != AbstractDecoder.NULL_VALUE) {
    923                                    conversation = (Conversation)skype.factory(Conversation.moduleID(), oid, skype);
    924                            }
    925                            return conversation;
    926                    }
    927
    928                    /**
    929                    This enumerator is used by both Contact and Account objects. Thus the items here can have slightly different meaning, depending on which context you will examine their values. In case of Contact, the values apply to a user - across all the instances that user has logged in with Skype. In case of Account, the capability is that of a local, currently logged in instance of Skype client. <br><br>The values that CAPABILITY items can have are also dependant on class context. In context of Contact, a capability can be CAPABILITY_MIXED. Which in case of CAPABILITY_VIDEO, for example, would mean that the remote use has logged in with different clients, some of which support video calls and some of which don't. In context of Account - there are no mixed result. Currently logged in Skype instance either supports video or it doesn't. <br> */
    930                    public enum CAPABILITY {
    931
    932                            /** For Account object, this is the same as CAPABILITY_CAN_BE_SENT_VM - it indicates that the currently logged in Skype instance supports voicemails. For Contact objects, it means that their remote system supports sending voicemails - there is no technical method for Skype to detect whether they are capable of receiving voicemails, so the assumption is that they can. <br>*/
    933                            CAPABILITY_VOICEMAIL(0),
    934
    935                            /** Indicates that the contact/account has SkypeOut and is thus capable of making PSTN calls. <br>*/
    936                            CAPABILITY_SKYPEOUT(1),
    937
    938                            /** Indicates that the contact/account has SkypeIn and is thus capable of answering PSTN calls. <br>*/
    939                            CAPABILITY_SKYPEIN(2),
    940
    941                            /** For contacts, this is a combination of CAPABILITY_VOICEMAIL for local account (local Skype client supports sending voicemails) and CAPABILITY_VOICEMAIL of the Contact - if the contact supports sending voicemails then hopefully they can also receive them. <br>*/
    942                            CAPABILITY_CAN_BE_SENT_VM(3),
    943
    944                            /** Indicates that Account/Contact supports call forwarding. <br>*/
    945                            CAPABILITY_CALL_FORWARD(4),
    946
    947                            /** Indicates that Account/Contact supports call video calls. <br>*/
    948                            CAPABILITY_VIDEO(5),
    949
    950                            /** In context of Contact, this indicates that the user is noticed running at least one Skype implementation that supports text messaging. Basically, it applies to a user. When applied to Account, the meaning is slightly different. In that case it indicates that currently running Skype implementation supports chat messaging. So, for Account objects, this is a node (rather than user) capability. <br>*/
    951                            CAPABILITY_TEXT(6),
    952
    953                            /** Indicates that the contact/account is flagged as SkypePrime service provider. This is linked to Account class SERVICE_PROVIDER_INFO property. <br>*/
    954                            CAPABILITY_SERVICE_PROVIDER(7),
    955
    956                            /** This is a legacy item, from the old times when conference calls with more than 5 people were limited to SkypePro accounts. In other words, this item is no longer relevant and will likely be removed at some point in future. <br>*/
    957                            CAPABILITY_LARGE_CONFERENCE(8),
    958
    959                            /** */
    960                            CAPABILITY_COMMERCIAL_CONTACT(9),
    961
    962                            /** Indicates that Account/Contact supports call transfers to PSTN numbers. <br>*/
    963                            CAPABILITY_PSTN_TRANSFER(10),
    964
    965                            /** Indicates that the user has had his chat capability removed by Skype. Basically, this means that the user is reported as spammer too many times. This applies for both Contact and Account objects - which means your client can check locally, if the currently logged in user has been marked as a spammer. <br>*/
    966                            CAPABILITY_TEXT_EVER(11),
    967
    968                            /** Indicates that the user (Account or Contact) has had his voice call capability removed by Skype. <br>*/
    969                            CAPABILITY_VOICE_EVER(12),
    970
    971                            /** Indicates that the instance of Skype client Account/Contact is or in Contact's case has at least occasionally been flagged as a mobile device. <br>*/
    972                            CAPABILITY_MOBILE_DEVICE(13),
    973
    974                            /** */
    975                            CAPABILITY_PUBLIC_CONTACT(14);
    976
    977                            private static final Map<Integer,CAPABILITY> lookup = new HashMap<Integer,CAPABILITY>();
    978
    979                            static {
    980                                    for(CAPABILITY s : EnumSet.allOf(CAPABILITY.class))
    981                                            lookup.put(s.getId(), s);
    982                            }
    983
    984                            private final int id;
    985
    986                            private CAPABILITY(int value) {
    987                                    this.id = value;
    988                            }
    989
    990                            public int getId() { return id; }
    991
    992                            public static CAPABILITY get(int code) {
    993                                    return lookup.get(code);
    994                            }
    995
    996                            public static CAPABILITY fromString(String s) {
    997                                    for (CAPABILITY p : lookup.values()) {
    998                                            if (p.toString() == s) {
    999                                                    return p;
    1000                                            }
    1001                                    }
    1002                                    return null;
    1003                            }
    1004                    }
    1005
    1006                    /**
    1007                    List of possible states of each of the Contact class CAPABILITY items. <br> */
    1008                    public enum CAPABILITYSTATUS {
    1009
    1010                            /** Contact does not have the capability <br>*/
    1011                            NO_CAPABILITY(0),
    1012
    1013                            /** Contact has occasionally logged in with Skype client that supports the capability. For example, a contact may have Skype client on several machines, only some of which have webcam - in which case CAPABILITY_VIDEO would have its value set as CAPABILITY_MIXED. <br>*/
    1014                            CAPABILITY_MIXED(1),
    1015
    1016                            /** Contact has the capability <br>*/
    1017                            CAPABILITY_EXISTS(2);
    1018
    1019                            private static final Map<Integer,CAPABILITYSTATUS> lookup = new HashMap<Integer,CAPABILITYSTATUS>();
    1020
    1021                            static {
    1022                                    for(CAPABILITYSTATUS s : EnumSet.allOf(CAPABILITYSTATUS.class))
    1023                                            lookup.put(s.getId(), s);
    1024                            }
    1025
    1026                            private final int id;
    1027
    1028                            private CAPABILITYSTATUS(int value) {
    1029                                    this.id = value;
    1030                            }
    1031
    1032                            public int getId() { return id; }
    1033
    1034                            public static CAPABILITYSTATUS get(int code) {
    1035                                    return lookup.get(code);
    1036                            }
    1037
    1038                            public static CAPABILITYSTATUS fromString(String s) {
    1039                                    for (CAPABILITYSTATUS p : lookup.values()) {
    1040                                            if (p.toString() == s) {
    1041                                                    return p;
    1042                                            }
    1043                                    }
    1044                                    return null;
    1045                            }
    1046                    }
    1047
    1048                    /**
    1049                     *Retrieves a Contact.Capability value. Sets P_REFRESHING to true while querying from server. This method is functionally the same as Contact.GetCapabilityStatus except that it returns a bool value rather than Contact.CAPABILITYSTATUS <br>
    1050                     * @param capability The target capability <br>
    1051                     * @param queryServer <br> - true: obtains the data from the p2p network/server, and sets P_REFRESHING to true for the duration  <br> - false: obtains the data from the local client <br>
    1052                     * @return result <br> - true: the Contact has the target capability through at least one of the Skype clients they have logged into. Corresponds to CAPABILITY_MIXED and CAPABILITY_EXISTS <br> - false: the Contact does not have the target capability. Corresponds to NO_CAPABILITY <br>
    1053                     */
    1054                    public boolean HasCapability( CAPABILITY capability, boolean queryServer) {
    1055
    1056                            Request request = null;
    1057                            try {
    1058                                    request = new XCallRequest(2,18);
    1059                            } catch (IOException e) {
    1060                                    e.printStackTrace();
    1061                                    if (skype.errorListener != null)
    1062                                            skype.errorListener.OnSkypeKitFatalError();
    1063                            }
    1064                            request.addParm('O',0,mObjectId);
    1065                            request.addParm('e',1,capability.getId());
    1066                            request.addParm('b',2,queryServer);
    1067
    1068                            Response r = skype.XCall((XCallRequest)request);
    1069
    1070                            if (r.isErrCall())
    1071                                    return false;
    1072
    1073                            boolean result = false;
    1074                            result = r.GetAsBoolean(1);
    1075                            return result;
    1076                    }
    1077
    1078                    /**
    1079                     *Retrieves a Contact.Capability value. Sets P_REFRESHING to true while querying from server. <br>
    1080                     * @param capability The target capability, see Contact.Capability enumerator. <br>
    1081                     * @param queryServer <br> - true: obtains the data from the p2p network/server, and sets P_REFRESHING to true for the duration  <br> - false: obtains the data from the local client <br>
    1082                     * @return status Status of the target capability. <br>
    1083                     */
    1084                    public CAPABILITYSTATUS GetCapabilityStatus( CAPABILITY capability, boolean queryServer) {
    1085
    1086                            Request request = null;
    1087                            try {
    1088                                    request = new XCallRequest(2,19);
    1089                            } catch (IOException e) {
    1090                                    e.printStackTrace();
    1091                                    if (skype.errorListener != null)
    1092                                            skype.errorListener.OnSkypeKitFatalError();
    1093                            }
    1094                            request.addParm('O',0,mObjectId);
    1095                            request.addParm('e',1,capability.getId());
    1096                            request.addParm('b',2,queryServer);
    1097
    1098                            Response r = skype.XCall((XCallRequest)request);
    1099
    1100                            if (r.isErrCall())
    1101                                    return null;
    1102
    1103                            CAPABILITYSTATUS capabilitystatus = null;
    1104                            capabilitystatus = CAPABILITYSTATUS.get(r.GetAsInt(1));
    1105                            return capabilitystatus;
    1106                    }
    1107
    1108                    /**
    1109                     *Refreshes all properties, capabilities, and statuses associated with this Contact from p2p/CBL, and sets P_REFRESHING to true for the duration. <br>
    1110                     */
    1111                    public void RefreshProfile() {
    1112
    1113                            Request request = null;
    1114                            try {
    1115                                    request = new XCallRequest(2,20);
    1116                            } catch (IOException e) {
    1117                                    e.printStackTrace();
    1118                                    if (skype.errorListener != null)
    1119                                            skype.errorListener.OnSkypeKitFatalError();
    1120                            }
    1121                            request.addParm('O',0,mObjectId);
    1122
    1123                            skype.XCall((XCallRequest)request);
    1124                    }
    1125
    1126
    1127            }