SipProfile.java revision cf95f5d26363d4cd3815d31f5798f932a7720c17
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 boolean mAllowOutgoingCall = false;
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 {@link 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
124         *      {@link #setOutboundProxy(String)} to 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 InvalidArgumentException if the port number is out of range
171         */
172        public Builder setPort(int port) throws InvalidArgumentException {
173            mUri.setPort(port);
174            return this;
175        }
176
177        /**
178         * Sets the protocol used to connect to the SIP server. Currently,
179         * only "UDP" and "TCP" are supported.
180         *
181         * @param protocol the protocol string
182         * @return this builder object
183         * @throws InvalidArgumentException if the protocol is not recognized
184         */
185        public Builder setProtocol(String protocol)
186                throws InvalidArgumentException {
187            if (protocol == null) {
188                throw new NullPointerException("protocol cannot be null");
189            }
190            protocol = protocol.toUpperCase();
191            if (!protocol.equals("UDP") && !protocol.equals("TCP")) {
192                throw new InvalidArgumentException(
193                        "unsupported protocol: " + protocol);
194            }
195            mProfile.mProtocol = protocol;
196            return this;
197        }
198
199        /**
200         * Sets the outbound proxy of the SIP server.
201         *
202         * @param outboundProxy the network address of the outbound proxy
203         * @return this builder object
204         */
205        public Builder setOutboundProxy(String outboundProxy) {
206            mProxyAddress = outboundProxy;
207            return this;
208        }
209
210        /**
211         * Sets the display name of the user.
212         *
213         * @param displayName display name of the user
214         * @return this builder object
215         */
216        public Builder setDisplayName(String displayName) {
217            mDisplayName = displayName;
218            return this;
219        }
220
221        /**
222         * Sets the send keep-alive flag.
223         *
224         * @param flag true if sending keep-alive message is required,
225         *      false otherwise
226         * @return this builder object
227         */
228        public Builder setSendKeepAlive(boolean flag) {
229            mProfile.mSendKeepAlive = flag;
230            return this;
231        }
232
233
234        /**
235         * Sets the auto. registration flag.
236         *
237         * @param flag true if the profile will be registered automatically,
238         *      false otherwise
239         * @return this builder object
240         */
241        public Builder setAutoRegistration(boolean flag) {
242            mProfile.mAutoRegistration = flag;
243            return this;
244        }
245
246        /**
247         * Sets the allow-outgoing-call flag.
248         *
249         * @param flag true if allowing to make outgoing call on the profile;
250         *      false otherwise
251         * @return this builder object
252         */
253        public Builder setOutgoingCallAllowed(boolean flag) {
254            mProfile.mAllowOutgoingCall = flag;
255            return this;
256        }
257
258        /**
259         * Builds and returns the SIP profile object.
260         *
261         * @return the profile object created
262         */
263        public SipProfile build() {
264            // remove password from URI
265            mProfile.mPassword = mUri.getUserPassword();
266            mUri.setUserPassword(null);
267            try {
268                mProfile.mAddress = mAddressFactory.createAddress(
269                        mDisplayName, mUri);
270                if (!TextUtils.isEmpty(mProxyAddress)) {
271                    SipURI uri = (SipURI)
272                            mAddressFactory.createURI(fix(mProxyAddress));
273                    mProfile.mProxyAddress = uri.getHost();
274                }
275            } catch (ParseException e) {
276                // must not occur
277                throw new RuntimeException(e);
278            }
279            return mProfile;
280        }
281    }
282
283    private SipProfile() {
284    }
285
286    private SipProfile(Parcel in) {
287        mAddress = (Address) in.readSerializable();
288        mProxyAddress = in.readString();
289        mPassword = in.readString();
290        mDomain = in.readString();
291        mProtocol = in.readString();
292        mProfileName = in.readString();
293        mSendKeepAlive = (in.readInt() == 0) ? false : true;
294        mAutoRegistration = (in.readInt() == 0) ? false : true;
295        mAllowOutgoingCall = (in.readInt() == 0) ? false : true;
296    }
297
298    /** @hide */
299    public void writeToParcel(Parcel out, int flags) {
300        out.writeSerializable(mAddress);
301        out.writeString(mProxyAddress);
302        out.writeString(mPassword);
303        out.writeString(mDomain);
304        out.writeString(mProtocol);
305        out.writeString(mProfileName);
306        out.writeInt(mSendKeepAlive ? 1 : 0);
307        out.writeInt(mAutoRegistration ? 1 : 0);
308        out.writeInt(mAllowOutgoingCall ? 1 : 0);
309    }
310
311    /** @hide */
312    public int describeContents() {
313        return 0;
314    }
315
316    /**
317     * Gets the SIP URI of this profile.
318     *
319     * @return the SIP URI of this profile
320     */
321    public SipURI getUri() {
322        return (SipURI) mAddress.getURI();
323    }
324
325    /**
326     * Gets the SIP URI string of this profile.
327     *
328     * @return the SIP URI string of this profile
329     */
330    public String getUriString() {
331        return mAddress.getURI().toString();
332    }
333
334    /**
335     * Gets the SIP address of this profile.
336     *
337     * @return the SIP address of this profile
338     */
339    public Address getSipAddress() {
340        return mAddress;
341    }
342
343    /**
344     * Gets the display name of the user.
345     *
346     * @return the display name of the user
347     */
348    public String getDisplayName() {
349        return mAddress.getDisplayName();
350    }
351
352    /**
353     * Gets the username.
354     *
355     * @return the username
356     */
357    public String getUserName() {
358        return getUri().getUser();
359    }
360
361    /**
362     * Gets the password.
363     *
364     * @return the password
365     */
366    public String getPassword() {
367        return mPassword;
368    }
369
370    /**
371     * Gets the SIP domain.
372     *
373     * @return the SIP domain
374     */
375    public String getSipDomain() {
376        return mDomain;
377    }
378
379    /**
380     * Gets the port number of the SIP server.
381     *
382     * @return the port number of the SIP server
383     */
384    public int getPort() {
385        int port = getUri().getPort();
386        return (port == -1) ? DEFAULT_PORT : port;
387    }
388
389    /**
390     * Gets the protocol used to connect to the server.
391     *
392     * @return the protocol
393     */
394    public String getProtocol() {
395        return mProtocol;
396    }
397
398    /**
399     * Gets the network address of the server outbound proxy.
400     *
401     * @return the network address of the server outbound proxy
402     */
403    public String getProxyAddress() {
404        return mProxyAddress;
405    }
406
407    /**
408     * Gets the (user-defined) name of the profile.
409     *
410     * @return name of the profile
411     */
412    public String getProfileName() {
413        return mProfileName;
414    }
415
416    /**
417     * Gets the flag of 'Sending keep-alive'.
418     *
419     * @return the flag of sending SIP keep-alive messages.
420     */
421    public boolean getSendKeepAlive() {
422        return mSendKeepAlive;
423    }
424
425    /**
426     * Gets the flag of 'Auto Registration'.
427     *
428     * @return the flag of registering the profile automatically.
429     */
430    public boolean getAutoRegistration() {
431        return mAutoRegistration;
432    }
433
434    /**
435     * Returns true if allowing to make outgoing calls on this profile.
436     */
437    public boolean isOutgoingCallAllowed() {
438        return mAllowOutgoingCall;
439    }
440}
441