1package eu.siacs.conversations.utils;
2
3import android.annotation.TargetApi;
4import android.content.Context;
5import android.net.ConnectivityManager;
6import android.net.LinkProperties;
7import android.net.Network;
8import android.net.RouteInfo;
9import android.os.Build;
10
11import java.net.Inet4Address;
12import java.net.InetAddress;
13import java.util.ArrayList;
14import java.util.List;
15
16import de.measite.minidns.dnsserverlookup.AbstractDNSServerLookupMechanism;
17import de.measite.minidns.dnsserverlookup.AndroidUsingExec;
18
19public class AndroidUsingLinkProperties extends AbstractDNSServerLookupMechanism {
20
21 private final Context context;
22
23 protected AndroidUsingLinkProperties(Context context) {
24 super(AndroidUsingLinkProperties.class.getSimpleName(), AndroidUsingExec.PRIORITY - 1);
25 this.context = context;
26 }
27
28 @Override
29 public boolean isAvailable() {
30 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
31 }
32
33 @Override
34 @TargetApi(21)
35 public String[] getDnsServerAddresses() {
36 ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
37 Network[] networks = connectivityManager == null ? null : connectivityManager.getAllNetworks();
38 if (networks == null) {
39 return new String[0];
40 }
41 List<String> servers = new ArrayList<>();
42 for(Network network : networks) {
43 LinkProperties linkProperties = connectivityManager.getLinkProperties(network);
44 if (linkProperties != null) {
45 if (hasDefaultRoute(linkProperties)) {
46 servers.addAll(0, getIPv4First(linkProperties.getDnsServers()));
47 } else {
48 servers.addAll(getIPv4First(linkProperties.getDnsServers()));
49 }
50 }
51 }
52 return servers.toArray(new String[servers.size()]);
53 }
54
55 private static List<String> getIPv4First(List<InetAddress> in) {
56 List<String> out = new ArrayList<>();
57 for(InetAddress addr : in) {
58 if (addr instanceof Inet4Address) {
59 out.add(0, addr.toString());
60 } else {
61 out.add(addr.toString());
62 }
63 }
64 return out;
65 }
66
67 @TargetApi(Build.VERSION_CODES.LOLLIPOP)
68 private static boolean hasDefaultRoute(LinkProperties linkProperties) {
69 for(RouteInfo route: linkProperties.getRoutes()) {
70 if (route.isDefaultRoute()) {
71 return true;
72 }
73 }
74 return false;
75 }
76}