e298c8f2ccafa4d932c7af1eaef7a5cb62850ee1
[android6bed4] / src / nl / openfortress / android6bed4 / EventListener.java
1
2 package nl.openfortress.android6bed4;
3
4
5 import java.net.NetworkInterface;
6 import java.net.InetAddress;
7 import java.net.SocketException;
8 import java.util.Enumeration;
9 import java.util.Collection;
10 import java.util.Vector;
11
12
13 import android.content.BroadcastReceiver;
14 import android.content.Intent;
15 import android.content.IntentFilter;
16 import android.content.Context;
17 import android.net.ConnectivityManager;
18
19
20 /* The EventListener class picks up signals from the Android OS,
21  * and processes them internally.
22  * 
23  * Upon receiving BOOT_COMPLETED, it will see if the user wishes
24  * to start 6bed4 at boot time. Since this presents a popup, this
25  * is a setting that must be explicitly configured.  More details:
26  * http://stackoverflow.com/questions/5051687/broadcastreceiver-not-receiving-boot-completed
27  * 
28  * Upon receiving CONNECTIVITY_ACTION, it will see if there is a
29  * default route over IPv6 that does not a 6bed4 address.  See:
30  * http://stackoverflow.com/questions/5276032/connectivity-action-intent-recieved-twice-when-wifi-connected
31  * http://developer.android.com/reference/android/net/ConnectivityManager.html 
32  */
33 class EventListener extends BroadcastReceiver {
34         
35         private TunnelService netcfg_target;
36         
37         public void onReceive (Context ctx, Intent intent) {
38                 String act = intent.getAction ();
39                 
40                 if (act.equals (ConnectivityManager.CONNECTIVITY_ACTION)) {
41                         //
42                         // The Network Configuration has changed.
43                         // The NetworkInfo for the affected network is sent as an extra
44                         if (netcfg_target == null) {
45                                 return;
46                         }
47                         try {
48                                 Collection <byte[]> ipv6list = new Vector <byte[]> ();
49                                 Enumeration <NetworkInterface> nif_iter = NetworkInterface.getNetworkInterfaces ();
50                                 while (nif_iter.hasMoreElements ()) { 
51                                         NetworkInterface nif = nif_iter.nextElement ();
52                                         try {
53                                                 if (nif.isUp ()) {
54                                                         Enumeration <InetAddress> adr_iter = nif.getInetAddresses ();
55                                                         while (adr_iter.hasMoreElements ()) {
56                                                                 InetAddress adr = adr_iter.nextElement ();
57                                                                 if (adr.isLoopbackAddress () || adr.isLinkLocalAddress () || adr.isAnyLocalAddress () || adr.isSiteLocalAddress () || adr.isMulticastAddress ()) {
58                                                                         continue;
59                                                                 }
60                                                                 byte ipv6addr [] = adr.getAddress ();
61                                                                 if (ipv6addr.length != 16) {
62                                                                         continue;
63                                                                 }
64                                                                 ipv6list.add (ipv6addr);
65                                                         }
66                                                 }
67                                         } catch (SocketException se) {
68                                                 ;       /* Ignore */
69                                         }
70                                         // Now tell the tunnel service about ipv6list
71                                         netcfg_target.notify_ipv6_addresses (ipv6list);
72                                 }
73                         } catch (SocketException se) {
74                                 ;       /* Ignore */
75                         }
76                         
77                 } else if (act.equals (Intent.ACTION_BOOT_COMPLETED)) {
78                         //
79                         // The system has finished booting.  Consider starting 6bed4
80                         // at this point (if the user is willing to deal with the popup
81                         // from the VPN toolkit at this point.
82                         Intent main = new Intent (Intent.ACTION_MAIN);
83                         main.addCategory (Intent.CATEGORY_HOME);
84                         ctx.startActivity (main);
85                 }
86                 
87         }
88         
89         /* Register this object as a network monitor reporting to the
90          * given TunnelService object when the set of local IPv6 addresses
91          * changes.  Note that the TunnelService is supposed to be smart
92          * enough to avoid endless loops; the monitor simply reports if a
93          * notification comes in, even if it is caused by 6bed4.
94          */
95         public void register_network_monitor (TunnelService target) {
96                 if (netcfg_target != null) {
97                         unregister_network_monitor ();
98                 }
99                 netcfg_target = target;
100                 IntentFilter intflt = new IntentFilter (Context.CONNECTIVITY_SERVICE);
101                 /* TODO -- how to get to the current context?!?
102                 Context ctx = getApplicationContext ();
103                 ctx.registerReceiver (this, intflt);
104                 */
105
106         }
107         
108         /* Unregister this object as a network monitor reporting to a
109          * once-setup TunnelService.
110          */
111         public void unregister_network_monitor () {
112                 //TODO// how to unregister for CONNECTIVITY_SERVICE broadcasts?
113                 netcfg_target = null;
114         }
115         
116 }