From afed2c2a3e92229eefd47fc0309fad23beeb4e7d Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 21 Jul 2015 12:06:27 +0200 Subject: [PATCH] android: Retrigger roam events on onLinkPropertiesChanged callbacks 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. --- .../android/logic/NetworkManager.java | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/frontends/android/src/org/strongswan/android/logic/NetworkManager.java b/src/frontends/android/src/org/strongswan/android/logic/NetworkManager.java index 8ea07f4c08..e3ab585b2c 100644 --- a/src/frontends/android/src/org/strongswan/android/logic/NetworkManager.java +++ b/src/frontends/android/src/org/strongswan/android/logic/NetworkManager.java @@ -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 @@ -15,17 +15,25 @@ 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); } -- 2.47.2