aboutsummaryrefslogtreecommitdiff
path: root/src/org/jivesoftware/smack/AndroidConnectionConfiguration.java
blob: 6ec05e024100fe82e2caf398b80a3b32ec1ed90e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package org.jivesoftware.smack;

import java.io.File;

import android.os.Build;

import org.jivesoftware.smack.proxy.ProxyInfo;
import org.jivesoftware.smack.util.DNSUtil;
import org.jivesoftware.smack.util.dns.HostAddress;

import java.util.List;

/**
 * This class wraps DNS SRV lookups for a new ConnectionConfiguration in a 
 * new thread, since Android API >= 11 (Honeycomb) does not allow network 
 * activity in the main thread. 
 * 
 * @author Florian Schmaus fschmaus@gmail.com
 *
 */
public class AndroidConnectionConfiguration extends ConnectionConfiguration {
    private static final int DEFAULT_TIMEOUT = 10000;
    
    /**
     * Creates a new ConnectionConfiguration for the specified service name.
     * A DNS SRV lookup will be performed to find out the actual host address
     * and port to use for the connection.
     *
     * @param serviceName the name of the service provided by an XMPP server.
     */
    public AndroidConnectionConfiguration(String serviceName) throws XMPPException {
        super();
        AndroidInit(serviceName, DEFAULT_TIMEOUT);
    }
    
    /**
     * 
     * @param serviceName
     * @param timeout
     * @throws XMPPException
     */
    public AndroidConnectionConfiguration(String serviceName, int timeout) throws XMPPException {
        super();
        AndroidInit(serviceName, timeout);
    }

    public AndroidConnectionConfiguration(String host, int port, String name) {
	super(host, port, name);
	AndroidInit();
    }

    private void AndroidInit() {
    	// API 14 is Ice Cream Sandwich
	if (Build.VERSION.SDK_INT >= 14) {
	    setTruststoreType("AndroidCAStore");
	    setTruststorePassword(null);
	    setTruststorePath(null);
	} else {
	    setTruststoreType("BKS");
	    String path = System.getProperty("javax.net.ssl.trustStore");
	    if (path == null)
		path = System.getProperty("java.home") + File.separator + "etc"
		    + File.separator + "security" + File.separator
		    + "cacerts.bks";
	    setTruststorePath(path);
	}
    }

    /**
     * 
     * @param serviceName
     * @param timeout
     * @throws XMPPException
     */
    private void AndroidInit(String serviceName, int timeout) throws XMPPException {
	AndroidInit();
        class DnsSrvLookupRunnable implements Runnable {
            String serviceName;
            List<HostAddress> addresses;

            public DnsSrvLookupRunnable(String serviceName) {
                this.serviceName = serviceName;
            }

            @Override
            public void run() {
                addresses = DNSUtil.resolveXMPPDomain(serviceName);
            }

            public List<HostAddress> getHostAddresses() {
                return addresses;
            }
        }

        DnsSrvLookupRunnable dnsSrv = new DnsSrvLookupRunnable(serviceName);
        Thread t = new Thread(dnsSrv, "dns-srv-lookup");
        t.start();
        try {
            t.join(timeout);
        } catch (InterruptedException e) {
            throw new XMPPException("DNS lookup timeout after " + timeout + "ms", e);
        }

        hostAddresses = dnsSrv.getHostAddresses();
        if (hostAddresses == null) {
        	throw new XMPPException("DNS lookup failure");
        }

        ProxyInfo proxy = ProxyInfo.forDefaultProxy();

        init(serviceName, proxy);
    }
}