Commit b4a783ff authored by Sylvain Berfini's avatar Sylvain Berfini 🎩

Improved android platfrom helper connectivity manager + added interactivity receiver

parent 1b268d0f
......@@ -221,6 +221,11 @@ void Core::enterForeground () {
d->notifyEnteringForeground();
}
bool Core::isInBackground () {
L_D();
return d->isInBackground;
}
// ---------------------------------------------------------------------------
// C-Core.
// ---------------------------------------------------------------------------
......
......@@ -79,6 +79,7 @@ public:
void enterBackground ();
void enterForeground ();
bool isInBackground ();
// ---------------------------------------------------------------------------
// C-Core.
......
......@@ -446,4 +446,14 @@ extern "C" JNIEXPORT void JNICALL Java_org_linphone_core_tools_AndroidPlatformHe
androidPlatformHelper->getCore()->doLater(fun);
}
extern "C" JNIEXPORT jboolean JNICALL Java_org_linphone_core_tools_AndroidPlatformHelper_isInBackground(JNIEnv *env, jobject thiz, jlong ptr) {
AndroidPlatformHelpers *androidPlatformHelper = static_cast<AndroidPlatformHelpers *>((void *)ptr);
return androidPlatformHelper->getCore()->isInBackground();
}
extern "C" JNIEXPORT void JNICALL Java_org_linphone_core_tools_AndroidPlatformHelper_enableKeepAlive(JNIEnv *env, jobject thiz, jlong ptr, jboolean enable) {
AndroidPlatformHelpers *androidPlatformHelper = static_cast<AndroidPlatformHelpers *>((void *)ptr);
linphone_core_enable_keep_alive(androidPlatformHelper->getCore()->getCCore(), enable ? TRUE : FALSE);
}
LINPHONE_END_NAMESPACE
package org.linphone.core.tools;
/*
InteractivityReceiver.java
Copyright (C) 2019 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import org.linphone.core.tools.Log;
/*
* Purpose of this receiver is to disable keep alives when screen is off
* */
public class InteractivityReceiver extends BroadcastReceiver {
private AndroidPlatformHelper mHelper;
public InteractivityReceiver(final AndroidPlatformHelper helper) {
mHelper = helper;
}
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equalsIgnoreCase(Intent.ACTION_SCREEN_ON)) {
Log.i("[Platform Helper] Device is in interactive mode");
mHelper.setInteractiveMode(true);
} else if (action.equalsIgnoreCase(Intent.ACTION_SCREEN_OFF)) {
Log.i("[Platform Helper] Device is not in interactive mode");
mHelper.setInteractiveMode(false);
}
}
}
/*
NetworkManager.java
Copyright (C) 2017 Belledonne Communications, Grenoble, France
Copyright (C) 2017 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
......@@ -22,15 +22,20 @@ package org.linphone.core.tools;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkInfo;
import org.linphone.core.tools.AndroidPlatformHelper;
/**
* Intercept network state changes and update linphone core.
*/
public class NetworkManager extends BroadcastReceiver {
public class NetworkManager extends BroadcastReceiver implements NetworkManagerInterface {
private AndroidPlatformHelper mHelper;
private IntentFilter mNetworkIntentFilter;
private ConnectivityManager mConnectivityManager;
public NetworkManager(AndroidPlatformHelper helper) {
mHelper = helper;
......@@ -38,12 +43,48 @@ public class NetworkManager extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Boolean lNoConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
Log.i("[Platform Helper] Network connectivity disabled: " + lNoConnectivity);
mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Log.i("[Platform Helper] [Network Manager] Broadcast receiver called");
if (mHelper != null) {
mHelper.postNetworkUpdateRunner();
}
}
public void registerNetworkCallbacks(Context context, ConnectivityManager connectivityManager) {
mNetworkIntentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
context.registerReceiver(this, mNetworkIntentFilter);
}
public void unregisterNetworkCallbacks(Context context, ConnectivityManager connectivityManager) {
context.unregisterReceiver(this);
}
public boolean isCurrentlyConnected(Context context, ConnectivityManager connectivityManager, boolean wifiOnly) {
NetworkInfo[] networkInfos = connectivityManager.getAllNetworkInfo();
boolean connected = false;
for (NetworkInfo networkInfo : networkInfos) {
Log.i("[Platform Helper] [Network Manager] Found network type: " + networkInfo.getTypeName());
if (networkInfo.isAvailable() && networkInfo.isConnected()) {
Log.i("[Platform Helper] [Network Manager] Network is available");
if (networkInfo.getType() != ConnectivityManager.TYPE_WIFI && wifiOnly) {
Log.i("[Platform Helper] [Network Manager] Wifi only mode enabled, skipping");
} else {
connected = true;
}
}
}
return connected;
}
public boolean hasHttpProxy(Context context, ConnectivityManager connectivityManager) {
return false;
}
public String getProxyHost(Context context, ConnectivityManager connectivityManager) {
return null;
}
public int getProxyPort(Context context, ConnectivityManager connectivityManager) {
return 0;
}
}
/*
NetworkManager.java
Copyright (C) 2017 Belledonne Communications, Grenoble, France
NetworkManagerAbove21.java
Copyright (C) 2017 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
......@@ -19,12 +19,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
package org.linphone.core.tools;
import android.annotation.TargetApi;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkInfo;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.os.Build;
......@@ -33,35 +34,90 @@ import org.linphone.core.tools.AndroidPlatformHelper;
/**
* Intercept network state changes and update linphone core.
*/
public class NetworkManagerAbove21 {
public class NetworkManagerAbove21 implements NetworkManagerInterface {
private AndroidPlatformHelper mHelper;
private ConnectivityManager.NetworkCallback mNetworkCallback;
public NetworkManagerAbove21(final AndroidPlatformHelper helper) {
mHelper = helper;
mNetworkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
Log.i("[Platform Helper] Network is available");
helper.postNetworkUpdateRunner();
Log.i("[Platform Helper] [Network Manager 21] A network is available");
mHelper.postNetworkUpdateRunner();
}
@Override
public void onLost(Network network) {
Log.i("[Platform Helper] Network is lost");
helper.postNetworkUpdateRunner();
Log.i("[Platform Helper] [Network Manager 21] A network has been lost");
mHelper.postNetworkUpdateRunner();
}
@Override
public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
Log.i("[Platform Helper] [Network Manager 21] onCapabilitiesChanged " + network.toString() + ", " + networkCapabilities.toString());
}
@Override
public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
Log.i("[Platform Helper] [Network Manager 21] onLinkPropertiesChanged " + network.toString() + ", " + linkProperties.toString());
}
@Override
public void onLosing(Network network, int maxMsToLive) {
Log.i("[Platform Helper] [Network Manager 21] onLosing " + network.toString());
}
@Override
public void onUnavailable() {
Log.i("[Platform Helper] [Network Manager 21] onUnavailable");
}
};
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void registerNetworkCallbacks(ConnectivityManager connectivityManager) {
public void registerNetworkCallbacks(Context context, ConnectivityManager connectivityManager) {
connectivityManager.registerNetworkCallback(
new NetworkRequest.Builder().build(),
mNetworkCallback
);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void unregisterNetworkCallbacks(ConnectivityManager connectivityManager) {
public void unregisterNetworkCallbacks(Context context, ConnectivityManager connectivityManager) {
connectivityManager.unregisterNetworkCallback(mNetworkCallback);
}
public boolean isCurrentlyConnected(Context context, ConnectivityManager connectivityManager, boolean wifiOnly) {
Network[] networks = connectivityManager.getAllNetworks();
boolean connected = false;
for (Network network : networks) {
NetworkInfo networkInfo = connectivityManager.getNetworkInfo(network);
Log.i("[Platform Helper] [Network Manager 21] Found network type: " + networkInfo.getTypeName());
if (networkInfo.isAvailable() && networkInfo.isConnected()) {
Log.i("[Platform Helper] [Network Manager 21] Network is available and connected");
if (networkInfo.getType() != ConnectivityManager.TYPE_WIFI && wifiOnly) {
Log.i("[Platform Helper] [Network Manager 21] Wifi only mode enabled, skipping");
} else {
NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
if (capabilities != null) {
Log.i("[Platform Helper] [Network Manager 21] Network capabilities are " + capabilities.toString());
connected = capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
&& capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
}
}
}
}
return connected;
}
public boolean hasHttpProxy(Context context, ConnectivityManager connectivityManager) {
return false;
}
public String getProxyHost(Context context, ConnectivityManager connectivityManager) {
return null;
}
public int getProxyPort(Context context, ConnectivityManager connectivityManager) {
return 0;
}
}
/*
NetworkManagerAbove24.java
Copyright (C) 2019 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.linphone.core.tools;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkInfo;
import android.net.NetworkCapabilities;
import android.net.ProxyInfo;
import android.net.NetworkRequest;
import android.os.Build;
import org.linphone.core.tools.AndroidPlatformHelper;
/**
* Intercept network state changes and update linphone core.
*/
public class NetworkManagerAbove24 implements NetworkManagerInterface {
private AndroidPlatformHelper mHelper;
private ConnectivityManager.NetworkCallback mNetworkCallback;
public NetworkManagerAbove24(final AndroidPlatformHelper helper) {
mHelper = helper;
mNetworkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
Log.i("[Platform Helper] [Network Manager 24] A network is available");
mHelper.postNetworkUpdateRunner();
}
@Override
public void onLost(Network network) {
Log.i("[Platform Helper] [Network Manager 24] A network has been lost");
mHelper.postNetworkUpdateRunner();
}
@Override
public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
Log.i("[Platform Helper] [Network Manager 24] onCapabilitiesChanged " + network.toString() + ", " + networkCapabilities.toString());
}
@Override
public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
Log.i("[Platform Helper] [Network Manager 24] onLinkPropertiesChanged " + network.toString() + ", " + linkProperties.toString());
}
@Override
public void onLosing(Network network, int maxMsToLive) {
Log.i("[Platform Helper] [Network Manager 24] onLosing " + network.toString());
}
@Override
public void onUnavailable() {
Log.i("[Platform Helper] [Network Manager 24] onUnavailable");
}
};
}
public void registerNetworkCallbacks(Context context, ConnectivityManager connectivityManager) {
int permissionGranted = context.getPackageManager().checkPermission(Manifest.permission.ACCESS_NETWORK_STATE, context.getPackageName());
Log.i("[Platform Helper] [Network Manager 24] ACCESS_NETWORK_STATE permission is " + (permissionGranted == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
if (permissionGranted == PackageManager.PERMISSION_GRANTED) {
connectivityManager.registerDefaultNetworkCallback(mNetworkCallback);
}
}
public void unregisterNetworkCallbacks(Context context, ConnectivityManager connectivityManager) {
connectivityManager.unregisterNetworkCallback(mNetworkCallback);
}
public boolean isCurrentlyConnected(Context context, ConnectivityManager connectivityManager, boolean wifiOnly) {
int restrictBackgroundStatus = connectivityManager.getRestrictBackgroundStatus();
if (restrictBackgroundStatus == ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED) {
// Device is restricting metered network activity while application is running on background.
// In this state, application should not try to use the network while running on background, because it would be denied.
Log.w("[Platform Helper] [Network Manager 24] Device is restricting metered network activity while application is running on background");
if (mHelper.isInBackground()) {
Log.w("[Platform Helper] [Network Manager 26] Device is in background, returning false");
return false;
}
}
Network[] networks = connectivityManager.getAllNetworks();
boolean connected = false;
for (Network network : networks) {
NetworkInfo networkInfo = connectivityManager.getNetworkInfo(network);
Log.i("[Platform Helper] [Network Manager 24] Found network type: " + networkInfo.getTypeName());
if (networkInfo.isAvailable() && networkInfo.isConnected()) {
Log.i("[Platform Helper] [Network Manager 24] Network is available and connected");
if (networkInfo.getType() != ConnectivityManager.TYPE_WIFI && wifiOnly) {
Log.i("[Platform Helper] [Network Manager 24] Wifi only mode enabled, skipping");
} else {
NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
if (capabilities != null) {
Log.i("[Platform Helper] [Network Manager 24] Network capabilities are " + capabilities.toString());
connected = capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
&& capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
&& capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
}
}
}
}
return connected;
}
public boolean hasHttpProxy(Context context, ConnectivityManager connectivityManager) {
ProxyInfo proxy = connectivityManager.getDefaultProxy();
if (proxy != null && proxy.getHost() != null) {
Log.i("[Platform Helper] [Network Manager 24] The active network is using a http proxy: " + proxy.toString());
return true;
}
Log.i("[Platform Helper] [Network Manager 24] The active network isn't using a http proxy: " + proxy.toString());
return false;
}
public String getProxyHost(Context context, ConnectivityManager connectivityManager) {
ProxyInfo proxy = connectivityManager.getDefaultProxy();
return proxy.getHost();
}
public int getProxyPort(Context context, ConnectivityManager connectivityManager) {
ProxyInfo proxy = connectivityManager.getDefaultProxy();
return proxy.getPort();
}
}
/*
NetworkManagerAbove26.java
Copyright (C) 2019 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.linphone.core.tools;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkInfo;
import android.net.NetworkCapabilities;
import android.net.ProxyInfo;
import android.net.NetworkRequest;
import android.os.Build;
import org.linphone.core.tools.AndroidPlatformHelper;
/**
* Intercept network state changes and update linphone core.
*/
public class NetworkManagerAbove26 implements NetworkManagerInterface {
private AndroidPlatformHelper mHelper;
private ConnectivityManager.NetworkCallback mNetworkCallback;
public NetworkManagerAbove26(final AndroidPlatformHelper helper) {
mHelper = helper;
mNetworkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
Log.i("[Platform Helper] [Network Manager 26] A network is available");
mHelper.updateNetworkReachability();
}
@Override
public void onLost(Network network) {
Log.i("[Platform Helper] [Network Manager 26] A network has been lost");
mHelper.updateNetworkReachability();
}
@Override
public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
Log.i("[Platform Helper] [Network Manager 26] onCapabilitiesChanged " + network.toString() + ", " + networkCapabilities.toString());
}
@Override
public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
Log.i("[Platform Helper] [Network Manager 26] onLinkPropertiesChanged " + network.toString() + ", " + linkProperties.toString());
}
@Override
public void onLosing(Network network, int maxMsToLive) {
Log.i("[Platform Helper] [Network Manager 26] onLosing " + network.toString());
}
@Override
public void onUnavailable() {
Log.i("[Platform Helper] [Network Manager 26] onUnavailable");
}
};
}
public void registerNetworkCallbacks(Context context, ConnectivityManager connectivityManager) {
int permissionGranted = context.getPackageManager().checkPermission(Manifest.permission.ACCESS_NETWORK_STATE, context.getPackageName());
Log.i("[Platform Helper] [Network Manager 26] ACCESS_NETWORK_STATE permission is " + (permissionGranted == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
if (permissionGranted == PackageManager.PERMISSION_GRANTED) {
connectivityManager.registerDefaultNetworkCallback(mNetworkCallback, mHelper.getHandler());
}
}
public void unregisterNetworkCallbacks(Context context, ConnectivityManager connectivityManager) {
connectivityManager.unregisterNetworkCallback(mNetworkCallback);
}
public boolean isCurrentlyConnected(Context context, ConnectivityManager connectivityManager, boolean wifiOnly) {
int restrictBackgroundStatus = connectivityManager.getRestrictBackgroundStatus();
if (restrictBackgroundStatus == ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED) {
// Device is restricting metered network activity while application is running on background.
// In this state, application should not try to use the network while running on background, because it would be denied.
Log.w("[Platform Helper] [Network Manager 26] Device is restricting metered network activity while application is running on background");
if (mHelper.isInBackground()) {
Log.w("[Platform Helper] [Network Manager 26] Device is in background, returning false");
return false;
}
}
Network[] networks = connectivityManager.getAllNetworks();
boolean connected = false;
for (Network network : networks) {
NetworkInfo networkInfo = connectivityManager.getNetworkInfo(network);
Log.i("[Platform Helper] [Network Manager 26] Found network type: " + networkInfo.getTypeName());
if (networkInfo.isAvailable() && networkInfo.isConnected()) {
Log.i("[Platform Helper] [Network Manager 26] Network is available and connected");
if (networkInfo.getType() != ConnectivityManager.TYPE_WIFI && wifiOnly) {
Log.i("[Platform Helper] [Network Manager 26] Wifi only mode enabled, skipping");
} else {
NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
if (capabilities != null) {
Log.i("[Platform Helper] [Network Manager 26] Network capabilities are " + capabilities.toString());
connected = capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
&& capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
&& capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
}
}
}
}
return connected;
}
public boolean hasHttpProxy(Context context, ConnectivityManager connectivityManager) {
ProxyInfo proxy = connectivityManager.getDefaultProxy();
if (proxy != null && proxy.getHost() != null){
Log.i("[Platform Helper] [Network Manager 26] The active network is using an http proxy: " + proxy.toString());
return true;
}
return false;
}
public String getProxyHost(Context context, ConnectivityManager connectivityManager) {
ProxyInfo proxy = connectivityManager.getDefaultProxy();
return proxy.getHost();
}
public int getProxyPort(Context context, ConnectivityManager connectivityManager) {
ProxyInfo proxy = connectivityManager.getDefaultProxy();
return proxy.getPort();
}
}
/*
NetworkManagerInterface.java
Copyright (C) 2019 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.linphone.core.tools;
import android.content.Context;
import android.net.ConnectivityManager;
public interface NetworkManagerInterface {
void registerNetworkCallbacks(Context context, ConnectivityManager connectivityManager);
void unregisterNetworkCallbacks(Context context, ConnectivityManager connectivityManager);
boolean isCurrentlyConnected(Context context, ConnectivityManager connectivityManager, boolean wifiOnly);
boolean hasHttpProxy(Context context, ConnectivityManager connectivityManager);
String getProxyHost(Context context, ConnectivityManager connectivityManager);
int getProxyPort(Context context, ConnectivityManager connectivityManager);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment