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

Commit 45e27327 authored by Sreeram Ramachandran's avatar Sreeram Ramachandran Committed by Android (Google) Code Review
Browse files

Merge "Allow VPNs to specify their underlying networks." into lmp-mr1-dev

parents aaea7e81 c2c0beab
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -17446,6 +17446,7 @@ package android.net {
    method public boolean protect(int);
    method public boolean protect(java.net.Socket);
    method public boolean protect(java.net.DatagramSocket);
    method public boolean setUnderlyingNetworks(android.net.Network[]);
    field public static final java.lang.String SERVICE_INTERFACE = "android.net.VpnService";
  }
@@ -17467,6 +17468,7 @@ package android.net {
    method public android.net.VpnService.Builder setConfigureIntent(android.app.PendingIntent);
    method public android.net.VpnService.Builder setMtu(int);
    method public android.net.VpnService.Builder setSession(java.lang.String);
    method public android.net.VpnService.Builder setUnderlyingNetworks(android.net.Network[]);
  }
}
+1 −0
Original line number Diff line number Diff line
@@ -170,4 +170,5 @@ interface IConnectivityManager

    boolean addVpnAddress(String address, int prefixLength);
    boolean removeVpnAddress(String address, int prefixLength);
    boolean setUnderlyingNetworksForVpn(in Network[] networks);
}
+55 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.net.Network;
import android.net.NetworkUtils;
import android.os.Binder;
import android.os.IBinder;
@@ -287,6 +288,46 @@ public class VpnService extends Service {
        }
    }

    /**
     * Sets the underlying networks used by the VPN for its upstream connections.
     *
     * Used by the system to know the actual networks that carry traffic for apps affected by this
     * VPN in order to present this information to the user (e.g., via status bar icons).
     *
     * This method only needs to be called if the VPN has explicitly bound its underlying
     * communications channels — such as the socket(s) passed to {@link #protect(int)} —
     * to a {@code Network} using APIs such as {@link Network#bindSocket} or {@link
     * Network#bindDatagramSocket}. The VPN should call this method every time the set of {@code
     * Network}s it is using changes.
     *
     * {@code networks} is one of the following:
     * <ul>
     * <li><strong>a non-empty array</strong>: an array of one or more {@link Network}s, in
     * decreasing preference order. For example, if this VPN uses both wifi and mobile (cellular)
     * networks to carry app traffic, but prefers or uses wifi more than mobile, wifi should appear
     * first in the array.</li>
     * <li><strong>an empty array</strong>: a zero-element array, meaning that the VPN has no
     * underlying network connection, and thus, app traffic will not be sent or received.</li>
     * <li><strong>null</strong>: (default) signifies that the VPN uses whatever is the system's
     * default network. I.e., it doesn't use the {@code bindSocket} or {@code bindDatagramSocket}
     * APIs mentioned above to send traffic over specific channels.
     * </ul>
     *
     * This call will succeed only if the VPN is currently established. For setting this value when
     * the VPN has not yet been established, see {@link Builder#setUnderlyingNetworks}.
     *
     * @param networks An array of networks the VPN uses to tunnel traffic to/from its servers.
     *
     * @return {@code true} on success.
     */
    public boolean setUnderlyingNetworks(Network[] networks) {
        try {
            return getService().setUnderlyingNetworksForVpn(networks);
        } catch (RemoteException e) {
            throw new IllegalStateException(e);
        }
    }

    /**
     * Return the communication interface to the service. This method returns
     * {@code null} on {@link Intent}s other than {@link #SERVICE_INTERFACE}
@@ -662,6 +703,20 @@ public class VpnService extends Service {
            return this;
        }

        /**
         * Sets the underlying networks used by the VPN for its upstream connections.
         *
         * @see VpnService#setUnderlyingNetworks
         *
         * @param networks An array of networks the VPN uses to tunnel traffic to/from its servers.
         *
         * @return this {@link Builder} object to facilitate chaining method calls.
         */
        public Builder setUnderlyingNetworks(Network[] networks) {
            mConfig.underlyingNetworks = networks != null ? networks.clone() : null;
            return this;
        }

        /**
         * Create a VPN interface using the parameters supplied to this
         * builder. The interface works on IP packets, and a file descriptor
+4 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.net.LinkAddress;
import android.net.Network;
import android.net.RouteInfo;
import android.os.Parcel;
import android.os.Parcelable;
@@ -99,6 +100,7 @@ public class VpnConfig implements Parcelable {
    public boolean allowBypass;
    public boolean allowIPv4;
    public boolean allowIPv6;
    public Network[] underlyingNetworks;

    public void updateAllowedFamilies(InetAddress address) {
        if (address instanceof Inet4Address) {
@@ -162,6 +164,7 @@ public class VpnConfig implements Parcelable {
        out.writeInt(allowBypass ? 1 : 0);
        out.writeInt(allowIPv4 ? 1 : 0);
        out.writeInt(allowIPv6 ? 1 : 0);
        out.writeTypedArray(underlyingNetworks, flags);
    }

    public static final Parcelable.Creator<VpnConfig> CREATOR =
@@ -186,6 +189,7 @@ public class VpnConfig implements Parcelable {
            config.allowBypass = in.readInt() != 0;
            config.allowIPv4 = in.readInt() != 0;
            config.allowIPv6 = in.readInt() != 0;
            config.underlyingNetworks = in.createTypedArray(Network.CREATOR);
            return config;
        }

+32 −0
Original line number Diff line number Diff line
@@ -865,6 +865,29 @@ public class ConnectivityService extends IConnectivityManager.Stub
        Network network = null;

        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;
                        }
                    }
                }
            }
        }

        if (nai != null) {
            synchronized (nai) {
                info = new NetworkInfo(nai.networkInfo);
@@ -4376,4 +4399,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
            return mVpns.get(user).removeAddress(address, prefixLength);
        }
    }

    @Override
    public boolean setUnderlyingNetworksForVpn(Network[] networks) {
        throwIfLockdownEnabled();
        int user = UserHandle.getUserId(Binder.getCallingUid());
        synchronized (mVpns) {
            return mVpns.get(user).setUnderlyingNetworks(networks);
        }
    }
}
Loading