summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Mortimer <sam@mortimer.me.uk>2019-08-16 02:40:55 (GMT)
committerLuca Stefani <luca.stefani.ge1@gmail.com>2019-08-20 08:53:08 (GMT)
commit368894d2a94ce3028243f7506a55e623a576865c (patch)
tree69b9b55724b507a837c3e9eced0b5069dc71a746
parent1416722f908465a1665285c53d9282710b530d39 (diff)
downloadframeworks_base-368894d2a94ce3028243f7506a55e623a576865c.zip
frameworks_base-368894d2a94ce3028243f7506a55e623a576865c.tar.gz
frameworks_base-368894d2a94ce3028243f7506a55e623a576865c.tar.bz2
fw/b: Add capability to allow tethering to use VPN upstreams
* Toggled on/off at runtime via a new hotspot lineage setting. * Dynamically updates the tethering upstream for existing hotspot clients as VPNs are brought up / down or the hotspot setting is changed. * This implementation depends on fw/b config_tether_upstream_automatic being set to true. Change-Id: I2ac0b4acc0ea686dfdf54561cb3428808e337160
-rw-r--r--services/core/java/com/android/server/connectivity/Tethering.java15
-rw-r--r--services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java26
2 files changed, 41 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 5105941..cd5dc46 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -65,6 +65,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
+import android.database.ContentObserver;
import android.hardware.usb.UsbManager;
import android.net.INetworkPolicyManager;
import android.net.INetworkStatsService;
@@ -123,6 +124,8 @@ import com.android.server.connectivity.tethering.TetheringInterfaceUtils;
import com.android.server.connectivity.tethering.UpstreamNetworkMonitor;
import com.android.server.net.BaseNetworkObserver;
+import lineageos.providers.LineageSettings;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.net.Inet4Address;
@@ -291,6 +294,18 @@ public class Tethering extends BaseNetworkObserver {
if (umi != null) {
umi.addUserRestrictionsListener(new TetheringUserRestrictionListener(this));
}
+
+ // Listen for allowing tethering upstream via VPN settings changes
+ final ContentObserver vpnSettingObserver = new ContentObserver(handler) {
+ @Override
+ public void onChange(boolean self) {
+ // Reconsider tethering upstream
+ mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED);
+ }
+ };
+ mContext.getContentResolver().registerContentObserver(LineageSettings.Secure.getUriFor(
+ LineageSettings.Secure.TETHERING_ALLOW_VPN_UPSTREAMS), false, vpnSettingObserver,
+ UserHandle.USER_ALL);
}
private WifiManager getWifiManager() {
diff --git a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
index f488be7..88fa0ae 100644
--- a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
@@ -21,6 +21,7 @@ import static android.net.ConnectivityManager.TYPE_NONE;
import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
@@ -28,6 +29,7 @@ import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Process;
+import android.os.UserHandle;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.IpPrefix;
@@ -45,6 +47,8 @@ import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.StateMachine;
+import lineageos.providers.LineageSettings;
+
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -103,6 +107,9 @@ public class UpstreamNetworkMonitor {
// The current upstream network used for tethering.
private Network mTetheringUpstreamNetwork;
+ // Set if the Internet is considered reachable via a VPN network
+ private Network mVpnInternetNetwork;
+
public UpstreamNetworkMonitor(Context ctx, StateMachine tgt, SharedLog log, int what) {
mContext = ctx;
mTarget = tgt;
@@ -145,6 +152,7 @@ public class UpstreamNetworkMonitor {
releaseCallback(mDefaultNetworkCallback);
mDefaultNetworkCallback = null;
mDefaultInternetNetwork = null;
+ mVpnInternetNetwork = null;
releaseCallback(mListenAllCallback);
mListenAllCallback = null;
@@ -237,6 +245,14 @@ public class UpstreamNetworkMonitor {
// Returns null if no current upstream available.
public NetworkState getCurrentPreferredUpstream() {
+ // Use VPN upstreams if hotspot settings allow.
+ if (mVpnInternetNetwork != null &&
+ LineageSettings.Secure.getIntForUser(mContext.getContentResolver(),
+ LineageSettings.Secure.TETHERING_ALLOW_VPN_UPSTREAMS,
+ 0, UserHandle.USER_CURRENT) == 1) {
+ return mNetworkMap.get(mVpnInternetNetwork);
+ }
+
final NetworkState dfltState = (mDefaultInternetNetwork != null)
? mNetworkMap.get(mDefaultInternetNetwork)
: null;
@@ -267,6 +283,8 @@ public class UpstreamNetworkMonitor {
private void handleNetCap(int callbackType, Network network, NetworkCapabilities newNc) {
if (callbackType == CALLBACK_DEFAULT_INTERNET) mDefaultInternetNetwork = network;
+ if (isVpnInternetNetwork(newNc)) mVpnInternetNetwork = network;
+
final NetworkState prev = mNetworkMap.get(network);
if (prev == null || newNc.equals(prev.networkCapabilities)) {
// Ignore notifications about networks for which we have not yet
@@ -340,6 +358,9 @@ public class UpstreamNetworkMonitor {
// callback gets notified.
if (callbackType == CALLBACK_DEFAULT_INTERNET) return;
}
+ if (network.equals(mVpnInternetNetwork)) {
+ mVpnInternetNetwork = null;
+ }
if (!mNetworkMap.containsKey(network)) {
// Ignore loss of networks about which we had not previously
@@ -505,6 +526,11 @@ public class UpstreamNetworkMonitor {
!isCellular(ns.networkCapabilities);
}
+ private static boolean isVpnInternetNetwork(NetworkCapabilities nc) {
+ return (nc != null) && !nc.hasCapability(NET_CAPABILITY_NOT_VPN) &&
+ nc.hasCapability(NET_CAPABILITY_INTERNET);
+ }
+
private static NetworkState findFirstDunNetwork(Iterable<NetworkState> netStates) {
for (NetworkState ns : netStates) {
if (isCellular(ns) && hasCapability(ns, NET_CAPABILITY_DUN)) return ns;