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