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