Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d6a7980d authored by Lorenzo Colitti's avatar Lorenzo Colitti
Browse files

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
parent 3bb5fdc7
Loading
Loading
Loading
Loading
+33 −19
Original line number Diff line number Diff line
@@ -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,27 +854,19 @@ 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)) {
        final Network[] networks = getVpnUnderlyingNetworks(uid);
        if (networks != null) {
            // getUnderlyingNetworks() returns:
                    // null => the VPN didn't specify anything, so we use the default.
            // 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.
                    Network[] networks = vpn.getUnderlyingNetworks();
                    if (networks != null) {
            if (networks.length > 0) {
                nai = getNetworkAgentInfoForNetwork(networks[0]);
            } else {
                nai = null;
            }
        }
                }
            }
        }

        if (nai != null) {
            synchronized (nai) {
@@ -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;
    }