Home | History | Annotate | Download | only in sip
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.net.sip;
     18 
     19 import android.os.Parcel;
     20 import android.os.Parcelable;
     21 import android.text.TextUtils;
     22 
     23 import java.io.Serializable;
     24 import java.text.ParseException;
     25 import javax.sip.InvalidArgumentException;
     26 import javax.sip.ListeningPoint;
     27 import javax.sip.PeerUnavailableException;
     28 import javax.sip.SipFactory;
     29 import javax.sip.address.Address;
     30 import javax.sip.address.AddressFactory;
     31 import javax.sip.address.SipURI;
     32 import javax.sip.address.URI;
     33 
     34 /**
     35  * Defines a SIP profile, including a SIP account, domain and server information.
     36  * <p>You can create a {@link SipProfile} using {@link
     37  * SipProfile.Builder}. You can also retrieve one from a {@link SipSession}, using {@link
     38  * SipSession#getLocalProfile} and {@link SipSession#getPeerProfile}.</p>
     39  */
     40 public class SipProfile implements Parcelable, Serializable, Cloneable {
     41     private static final long serialVersionUID = 1L;
     42     private static final int DEFAULT_PORT = 5060;
     43     private Address mAddress;
     44     private String mProxyAddress;
     45     private String mPassword;
     46     private String mDomain;
     47     private String mProtocol = ListeningPoint.UDP;
     48     private String mProfileName;
     49     private boolean mSendKeepAlive = false;
     50     private boolean mAutoRegistration = true;
     51     private transient int mCallingUid = 0;
     52 
     53     public static final Parcelable.Creator<SipProfile> CREATOR =
     54             new Parcelable.Creator<SipProfile>() {
     55                 public SipProfile createFromParcel(Parcel in) {
     56                     return new SipProfile(in);
     57                 }
     58 
     59                 public SipProfile[] newArray(int size) {
     60                     return new SipProfile[size];
     61                 }
     62             };
     63 
     64     /**
     65      * Helper class for creating a {@link SipProfile}.
     66      */
     67     public static class Builder {
     68         private AddressFactory mAddressFactory;
     69         private SipProfile mProfile = new SipProfile();
     70         private SipURI mUri;
     71         private String mDisplayName;
     72         private String mProxyAddress;
     73 
     74         {
     75             try {
     76                 mAddressFactory =
     77                         SipFactory.getInstance().createAddressFactory();
     78             } catch (PeerUnavailableException e) {
     79                 throw new RuntimeException(e);
     80             }
     81         }
     82 
     83         /**
     84          * Creates a builder based on the given profile.
     85          */
     86         public Builder(SipProfile profile) {
     87             if (profile == null) throw new NullPointerException();
     88             try {
     89                 mProfile = (SipProfile) profile.clone();
     90             } catch (CloneNotSupportedException e) {
     91                 throw new RuntimeException("should not occur", e);
     92             }
     93             mProfile.mAddress = null;
     94             mUri = profile.getUri();
     95             mUri.setUserPassword(profile.getPassword());
     96             mDisplayName = profile.getDisplayName();
     97             mProxyAddress = profile.getProxyAddress();
     98         }
     99 
    100         /**
    101          * Constructor.
    102          *
    103          * @param uriString the URI string as "sip:<user_name>@<domain>"
    104          * @throws ParseException if the string is not a valid URI
    105          */
    106         public Builder(String uriString) throws ParseException {
    107             if (uriString == null) {
    108                 throw new NullPointerException("uriString cannot be null");
    109             }
    110             URI uri = mAddressFactory.createURI(fix(uriString));
    111             if (uri instanceof SipURI) {
    112                 mUri = (SipURI) uri;
    113             } else {
    114                 throw new ParseException(uriString + " is not a SIP URI", 0);
    115             }
    116             mProfile.mDomain = mUri.getHost();
    117         }
    118 
    119         /**
    120          * Constructor.
    121          *
    122          * @param username username of the SIP account
    123          * @param serverDomain the SIP server domain; if the network address
    124          *      is different from the domain, use {@link #setOutboundProxy} to
    125          *      set server address
    126          * @throws ParseException if the parameters are not valid
    127          */
    128         public Builder(String username, String serverDomain)
    129                 throws ParseException {
    130             if ((username == null) || (serverDomain == null)) {
    131                 throw new NullPointerException(
    132                         "username and serverDomain cannot be null");
    133             }
    134             mUri = mAddressFactory.createSipURI(username, serverDomain);
    135             mProfile.mDomain = serverDomain;
    136         }
    137 
    138         private String fix(String uriString) {
    139             return (uriString.trim().toLowerCase().startsWith("sip:")
    140                     ? uriString
    141                     : "sip:" + uriString);
    142         }
    143 
    144         /**
    145          * Sets the name of the profile. This name is given by user.
    146          *
    147          * @param name name of the profile
    148          * @return this builder object
    149          */
    150         public Builder setProfileName(String name) {
    151             mProfile.mProfileName = name;
    152             return this;
    153         }
    154 
    155         /**
    156          * Sets the password of the SIP account
    157          *
    158          * @param password password of the SIP account
    159          * @return this builder object
    160          */
    161         public Builder setPassword(String password) {
    162             mUri.setUserPassword(password);
    163             return this;
    164         }
    165 
    166         /**
    167          * Sets the port number of the server. By default, it is 5060.
    168          *
    169          * @param port port number of the server
    170          * @return this builder object
    171          * @throws IllegalArgumentException if the port number is out of range
    172          */
    173         public Builder setPort(int port) throws IllegalArgumentException {
    174             try {
    175                 mUri.setPort(port);
    176                 return this;
    177             } catch (InvalidArgumentException e) {
    178                 throw new IllegalArgumentException(e);
    179             }
    180         }
    181 
    182         /**
    183          * Sets the protocol used to connect to the SIP server. Currently,
    184          * only "UDP" and "TCP" are supported.
    185          *
    186          * @param protocol the protocol string
    187          * @return this builder object
    188          * @throws IllegalArgumentException if the protocol is not recognized
    189          */
    190         public Builder setProtocol(String protocol)
    191                 throws IllegalArgumentException {
    192             if (protocol == null) {
    193                 throw new NullPointerException("protocol cannot be null");
    194             }
    195             protocol = protocol.toUpperCase();
    196             if (!protocol.equals("UDP") && !protocol.equals("TCP")) {
    197                 throw new IllegalArgumentException(
    198                         "unsupported protocol: " + protocol);
    199             }
    200             mProfile.mProtocol = protocol;
    201             return this;
    202         }
    203 
    204         /**
    205          * Sets the outbound proxy of the SIP server.
    206          *
    207          * @param outboundProxy the network address of the outbound proxy
    208          * @return this builder object
    209          */
    210         public Builder setOutboundProxy(String outboundProxy) {
    211             mProxyAddress = outboundProxy;
    212             return this;
    213         }
    214 
    215         /**
    216          * Sets the display name of the user.
    217          *
    218          * @param displayName display name of the user
    219          * @return this builder object
    220          */
    221         public Builder setDisplayName(String displayName) {
    222             mDisplayName = displayName;
    223             return this;
    224         }
    225 
    226         /**
    227          * Sets the send keep-alive flag.
    228          *
    229          * @param flag true if sending keep-alive message is required,
    230          *      false otherwise
    231          * @return this builder object
    232          */
    233         public Builder setSendKeepAlive(boolean flag) {
    234             mProfile.mSendKeepAlive = flag;
    235             return this;
    236         }
    237 
    238 
    239         /**
    240          * Sets the auto. registration flag.
    241          *
    242          * @param flag true if the profile will be registered automatically,
    243          *      false otherwise
    244          * @return this builder object
    245          */
    246         public Builder setAutoRegistration(boolean flag) {
    247             mProfile.mAutoRegistration = flag;
    248             return this;
    249         }
    250 
    251         /**
    252          * Builds and returns the SIP profile object.
    253          *
    254          * @return the profile object created
    255          */
    256         public SipProfile build() {
    257             // remove password from URI
    258             mProfile.mPassword = mUri.getUserPassword();
    259             mUri.setUserPassword(null);
    260             try {
    261                 mProfile.mAddress = mAddressFactory.createAddress(
    262                         mDisplayName, mUri);
    263                 if (!TextUtils.isEmpty(mProxyAddress)) {
    264                     SipURI uri = (SipURI)
    265                             mAddressFactory.createURI(fix(mProxyAddress));
    266                     mProfile.mProxyAddress = uri.getHost();
    267                 }
    268             } catch (ParseException e) {
    269                 // must not occur
    270                 throw new RuntimeException(e);
    271             }
    272             return mProfile;
    273         }
    274     }
    275 
    276     private SipProfile() {
    277     }
    278 
    279     private SipProfile(Parcel in) {
    280         mAddress = (Address) in.readSerializable();
    281         mProxyAddress = in.readString();
    282         mPassword = in.readString();
    283         mDomain = in.readString();
    284         mProtocol = in.readString();
    285         mProfileName = in.readString();
    286         mSendKeepAlive = (in.readInt() == 0) ? false : true;
    287         mAutoRegistration = (in.readInt() == 0) ? false : true;
    288         mCallingUid = in.readInt();
    289     }
    290 
    291     @Override
    292     public void writeToParcel(Parcel out, int flags) {
    293         out.writeSerializable(mAddress);
    294         out.writeString(mProxyAddress);
    295         out.writeString(mPassword);
    296         out.writeString(mDomain);
    297         out.writeString(mProtocol);
    298         out.writeString(mProfileName);
    299         out.writeInt(mSendKeepAlive ? 1 : 0);
    300         out.writeInt(mAutoRegistration ? 1 : 0);
    301         out.writeInt(mCallingUid);
    302     }
    303 
    304     @Override
    305     public int describeContents() {
    306         return 0;
    307     }
    308 
    309     /**
    310      * Gets the SIP URI of this profile.
    311      *
    312      * @return the SIP URI of this profile
    313      * @hide
    314      */
    315     public SipURI getUri() {
    316         return (SipURI) mAddress.getURI();
    317     }
    318 
    319     /**
    320      * Gets the SIP URI string of this profile.
    321      *
    322      * @return the SIP URI string of this profile
    323      */
    324     public String getUriString() {
    325         return mAddress.getURI().toString();
    326     }
    327 
    328     /**
    329      * Gets the SIP address of this profile.
    330      *
    331      * @return the SIP address of this profile
    332      * @hide
    333      */
    334     public Address getSipAddress() {
    335         return mAddress;
    336     }
    337 
    338     /**
    339      * Gets the display name of the user.
    340      *
    341      * @return the display name of the user
    342      */
    343     public String getDisplayName() {
    344         return mAddress.getDisplayName();
    345     }
    346 
    347     /**
    348      * Gets the username.
    349      *
    350      * @return the username
    351      */
    352     public String getUserName() {
    353         return getUri().getUser();
    354     }
    355 
    356     /**
    357      * Gets the password.
    358      *
    359      * @return the password
    360      */
    361     public String getPassword() {
    362         return mPassword;
    363     }
    364 
    365     /**
    366      * Gets the SIP domain.
    367      *
    368      * @return the SIP domain
    369      */
    370     public String getSipDomain() {
    371         return mDomain;
    372     }
    373 
    374     /**
    375      * Gets the port number of the SIP server.
    376      *
    377      * @return the port number of the SIP server
    378      */
    379     public int getPort() {
    380         int port = getUri().getPort();
    381         return (port == -1) ? DEFAULT_PORT : port;
    382     }
    383 
    384     /**
    385      * Gets the protocol used to connect to the server.
    386      *
    387      * @return the protocol
    388      */
    389     public String getProtocol() {
    390         return mProtocol;
    391     }
    392 
    393     /**
    394      * Gets the network address of the server outbound proxy.
    395      *
    396      * @return the network address of the server outbound proxy
    397      */
    398     public String getProxyAddress() {
    399         return mProxyAddress;
    400     }
    401 
    402     /**
    403      * Gets the (user-defined) name of the profile.
    404      *
    405      * @return name of the profile
    406      */
    407     public String getProfileName() {
    408         return mProfileName;
    409     }
    410 
    411     /**
    412      * Gets the flag of 'Sending keep-alive'.
    413      *
    414      * @return the flag of sending SIP keep-alive messages.
    415      */
    416     public boolean getSendKeepAlive() {
    417         return mSendKeepAlive;
    418     }
    419 
    420     /**
    421      * Gets the flag of 'Auto Registration'.
    422      *
    423      * @return the flag of registering the profile automatically.
    424      */
    425     public boolean getAutoRegistration() {
    426         return mAutoRegistration;
    427     }
    428 
    429     /**
    430      * Sets the calling process's Uid in the sip service.
    431      * @hide
    432      */
    433     public void setCallingUid(int uid) {
    434         mCallingUid = uid;
    435     }
    436 
    437     /**
    438      * Gets the calling process's Uid in the sip settings.
    439      * @hide
    440      */
    441     public int getCallingUid() {
    442         return mCallingUid;
    443     }
    444 }
    445