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