From d6a7980dd9a52f082091cf000095b77a9d44565d Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 5 Feb 2015 13:57:17 +0900 Subject: Make getNetworkInfo() take into account VPN underlying networks. If a user is subject to a VPN, getActiveNetworkInfo() will return the VPN's underlying network (e.g., TYPE_WIFI), so that apps that call getActiveNetworkInfo to answer questions like "is the device connected to wifi?" will continue to work. Make getNetworkInfo do this as well: if the query is for a network type that is underlying the current user's VPN, then return that network. Bug: 19196545 Change-Id: Ic5a651735b927c758594a26d26a03fbd704b52e6 --- .../com/android/server/ConnectivityService.java | 52 ++++++++++++++-------- 1 file changed, 33 insertions(+), 19 deletions(-) (limited to 'services/core/java') diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 944f1c0..551a5dc 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -832,6 +832,19 @@ public class ConnectivityService extends IConnectivityManager.Stub } }; + private Network[] getVpnUnderlyingNetworks(int uid) { + if (!mLockdownEnabled) { + int user = UserHandle.getUserId(uid); + synchronized (mVpns) { + Vpn vpn = mVpns.get(user); + if (vpn != null && vpn.appliesToUid(uid)) { + return vpn.getUnderlyingNetworks(); + } + } + } + return null; + } + private NetworkState getUnfilteredActiveNetworkState(int uid) { NetworkInfo info = null; LinkProperties lp = null; @@ -841,25 +854,17 @@ public class ConnectivityService extends IConnectivityManager.Stub NetworkAgentInfo nai = mNetworkForRequestId.get(mDefaultRequest.requestId); - if (!mLockdownEnabled) { - int user = UserHandle.getUserId(uid); - synchronized (mVpns) { - Vpn vpn = mVpns.get(user); - if (vpn != null && vpn.appliesToUid(uid)) { - // getUnderlyingNetworks() returns: - // null => the VPN didn't specify anything, so we use the default. - // empty array => the VPN explicitly said "no default network". - // non-empty array => the VPN specified one or more default networks; we use the - // first one. - Network[] networks = vpn.getUnderlyingNetworks(); - if (networks != null) { - if (networks.length > 0) { - nai = getNetworkAgentInfoForNetwork(networks[0]); - } else { - nai = null; - } - } - } + final Network[] networks = getVpnUnderlyingNetworks(uid); + if (networks != null) { + // getUnderlyingNetworks() returns: + // null => there was no VPN, or the VPN didn't specify anything, so we use the default. + // empty array => the VPN explicitly said "no default network". + // non-empty array => the VPN specified one or more default networks; we use the + // first one. + if (networks.length > 0) { + nai = getNetworkAgentInfoForNetwork(networks[0]); + } else { + nai = null; } } @@ -990,6 +995,15 @@ public class ConnectivityService extends IConnectivityManager.Stub public NetworkInfo getNetworkInfo(int networkType) { enforceAccessPermission(); final int uid = Binder.getCallingUid(); + if (getVpnUnderlyingNetworks(uid) != null) { + // A VPN is active, so we may need to return one of its underlying networks. This + // information is not available in LegacyTypeTracker, so we have to get it from + // getUnfilteredActiveNetworkState. + NetworkState state = getUnfilteredActiveNetworkState(uid); + if (state.networkInfo != null && state.networkInfo.getType() == networkType) { + return getFilteredNetworkInfo(state.networkInfo, state.linkProperties, uid); + } + } NetworkState state = getFilteredNetworkState(networkType, uid); return state.networkInfo; } -- cgit v1.1