Home | History | Annotate | Download | only in smack
      1 package org.jivesoftware.smack;
      2 
      3 import java.io.File;
      4 
      5 import android.os.Build;
      6 
      7 import org.jivesoftware.smack.proxy.ProxyInfo;
      8 import org.jivesoftware.smack.util.DNSUtil;
      9 import org.jivesoftware.smack.util.dns.HostAddress;
     10 
     11 import java.util.List;
     12 
     13 /**
     14  * This class wraps DNS SRV lookups for a new ConnectionConfiguration in a
     15  * new thread, since Android API >= 11 (Honeycomb) does not allow network
     16  * activity in the main thread.
     17  *
     18  * @author Florian Schmaus fschmaus (at) gmail.com
     19  *
     20  */
     21 public class AndroidConnectionConfiguration extends ConnectionConfiguration {
     22     private static final int DEFAULT_TIMEOUT = 10000;
     23 
     24     /**
     25      * Creates a new ConnectionConfiguration for the specified service name.
     26      * A DNS SRV lookup will be performed to find out the actual host address
     27      * and port to use for the connection.
     28      *
     29      * @param serviceName the name of the service provided by an XMPP server.
     30      */
     31     public AndroidConnectionConfiguration(String serviceName) throws XMPPException {
     32         super();
     33         AndroidInit(serviceName, DEFAULT_TIMEOUT);
     34     }
     35 
     36     /**
     37      *
     38      * @param serviceName
     39      * @param timeout
     40      * @throws XMPPException
     41      */
     42     public AndroidConnectionConfiguration(String serviceName, int timeout) throws XMPPException {
     43         super();
     44         AndroidInit(serviceName, timeout);
     45     }
     46 
     47     public AndroidConnectionConfiguration(String host, int port, String name) {
     48 	super(host, port, name);
     49 	AndroidInit();
     50     }
     51 
     52     private void AndroidInit() {
     53     	// API 14 is Ice Cream Sandwich
     54 	if (Build.VERSION.SDK_INT >= 14) {
     55 	    setTruststoreType("AndroidCAStore");
     56 	    setTruststorePassword(null);
     57 	    setTruststorePath(null);
     58 	} else {
     59 	    setTruststoreType("BKS");
     60 	    String path = System.getProperty("javax.net.ssl.trustStore");
     61 	    if (path == null)
     62 		path = System.getProperty("java.home") + File.separator + "etc"
     63 		    + File.separator + "security" + File.separator
     64 		    + "cacerts.bks";
     65 	    setTruststorePath(path);
     66 	}
     67     }
     68 
     69     /**
     70      *
     71      * @param serviceName
     72      * @param timeout
     73      * @throws XMPPException
     74      */
     75     private void AndroidInit(String serviceName, int timeout) throws XMPPException {
     76 	AndroidInit();
     77         class DnsSrvLookupRunnable implements Runnable {
     78             String serviceName;
     79             List<HostAddress> addresses;
     80 
     81             public DnsSrvLookupRunnable(String serviceName) {
     82                 this.serviceName = serviceName;
     83             }
     84 
     85             @Override
     86             public void run() {
     87                 addresses = DNSUtil.resolveXMPPDomain(serviceName);
     88             }
     89 
     90             public List<HostAddress> getHostAddresses() {
     91                 return addresses;
     92             }
     93         }
     94 
     95         DnsSrvLookupRunnable dnsSrv = new DnsSrvLookupRunnable(serviceName);
     96         Thread t = new Thread(dnsSrv, "dns-srv-lookup");
     97         t.start();
     98         try {
     99             t.join(timeout);
    100         } catch (InterruptedException e) {
    101             throw new XMPPException("DNS lookup timeout after " + timeout + "ms", e);
    102         }
    103 
    104         hostAddresses = dnsSrv.getHostAddresses();
    105         if (hostAddresses == null) {
    106         	throw new XMPPException("DNS lookup failure");
    107         }
    108 
    109         ProxyInfo proxy = ProxyInfo.forDefaultProxy();
    110 
    111         init(serviceName, proxy);
    112     }
    113 }
    114