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