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