]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
android: Retrigger roam events on onLinkPropertiesChanged callbacks android-updates-linkprops
authorTobias Brunner <tobias@strongswan.org>
Tue, 21 Jul 2015 10:06:27 +0000 (12:06 +0200)
committerTobias Brunner <tobias@strongswan.org>
Tue, 21 Jul 2015 12:32:10 +0000 (14:32 +0200)
In dual-stack environments the IPv6 connectivity (via autoconfiguration)
might be established before the IPv4 connectivity (via DHCP).  It seems
Android triggers the CONNECTIVITY_ACTION broadcast already when the first
family is fully configured.  At that time we might not be able to find an
IPv4 source address.  And since Android does not trigger the broadcast
again if IPv4 connectivity is established, the connection is broken
afterwards.

Since Android 5.0 ConnectivityManager provides a new callback framework.
There the onLinkPropertiesChanged callback is triggered on the active
interface if e.g. new IP addresses or routes get added.  We can use
this to trigger additional roaming events when the IPv4 connectivity is
established later.  It might get triggered a bit more often than we
like, and it might get triggered when not needed (e.g. if IPv4
connectivity is established before IPv6).

 #865.

src/frontends/android/src/org/strongswan/android/logic/NetworkManager.java

index 8ea07f4c08d728558264fbc49ca0932167f6e179..e3ab585b2cc7faeaafb0e833b01da139e341bba7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2013 Tobias Brunner
+ * Copyright (C) 2012-2015 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
 
 package org.strongswan.android.logic;
 
+import android.annotation.TargetApi;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.LinkProperties;
+import android.net.Network;
 import android.net.NetworkInfo;
+import android.net.NetworkRequest;
+import android.os.Build;
 
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
 public class NetworkManager extends BroadcastReceiver
 {
        private final Context mContext;
        private boolean mRegistered;
+       private NetworkCallback mCallback;
 
        public NetworkManager(Context context)
        {
@@ -34,11 +42,34 @@ public class NetworkManager extends BroadcastReceiver
 
        public void Register()
        {
+               if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
+               {
+                       this.mCallback = new ConnectivityManager.NetworkCallback() {
+                               @Override
+                               public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties)
+                               {
+                                       /* triggering the networkChanged callback again is needed
+                                        * in some scenarios where the broadcast comes before IPv4
+                                        * connectivity is fully established.  disadvantage is that
+                                        * it might be triggered a bit often and even when not
+                                        * required */
+                                       /* this seems only to get triggered when connected */
+                                       networkChanged(false);
+                               }
+                       };
+                       ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+                       cm.registerNetworkCallback(new NetworkRequest.Builder().build(), this.mCallback);
+               }
                mContext.registerReceiver(this, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
        }
 
        public void Unregister()
        {
+               if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
+               {
+                       ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+                       cm.unregisterNetworkCallback(this.mCallback);
+               }
                mContext.unregisterReceiver(this);
        }