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

Commit 5a561320 authored by Lorenzo Colitti's avatar Lorenzo Colitti Committed by Gerrit Code Review
Browse files

Merge changes Iec22ff63,Iaca8a7cc

* changes:
  Stop using VPNs in getDefaultNetworkCapabilitiesForUser.
  Inform ConnectivityService about always-on VPN lockdown.
parents b9ba6a8d 1a0836e3
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Range;
import android.util.SparseIntArray;

import com.android.connectivity.aidl.INetworkAgent;
@@ -73,10 +74,12 @@ import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -1162,6 +1165,55 @@ public class ConnectivityManager {
        }
    }

    /**
     * Adds or removes a requirement for given UID ranges to use the VPN.
     *
     * If set to {@code true}, informs the system that the UIDs in the specified ranges must not
     * have any connectivity except if a VPN is connected and applies to the UIDs, or if the UIDs
     * otherwise have permission to bypass the VPN (e.g., because they have the
     * {@link android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS} permission, or when
     * using a socket protected by a method such as {@link VpnService#protect(DatagramSocket)}. If
     * set to {@code false}, a previously-added restriction is removed.
     * <p>
     * Each of the UID ranges specified by this method is added and removed as is, and no processing
     * is performed on the ranges to de-duplicate, merge, split, or intersect them. In order to
     * remove a previously-added range, the exact range must be removed as is.
     * <p>
     * The changes are applied asynchronously and may not have been applied by the time the method
     * returns. Apps will be notified about any changes that apply to them via
     * {@link NetworkCallback#onBlockedStatusChanged} callbacks called after the changes take
     * effect.
     * <p>
     * This method should be called only by the VPN code.
     *
     * @param ranges the UID ranges to restrict
     * @param requireVpn whether the specified UID ranges must use a VPN
     *
     * TODO: expose as @SystemApi.
     * @hide
     */
    @RequiresPermission(anyOf = {
            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
            android.Manifest.permission.NETWORK_STACK})
    public void setRequireVpnForUids(boolean requireVpn,
            @NonNull Collection<Range<Integer>> ranges) {
        Objects.requireNonNull(ranges);
        // The Range class is not parcelable. Convert to UidRange, which is what is used internally.
        // This method is not necessarily expected to be used outside the system server, so
        // parceling may not be necessary, but it could be used out-of-process, e.g., by the network
        // stack process, or by tests.
        UidRange[] rangesArray = new UidRange[ranges.size()];
        int index = 0;
        for (Range<Integer> range : ranges) {
            rangesArray[index++] = new UidRange(range.getLower(), range.getUpper());
        }
        try {
            mService.setRequireVpnForUids(requireVpn, rangesArray);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Returns details about the currently active default data network
     * for a given uid.  This is for internal use only to avoid spying
+2 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.net.NetworkRequest;
import android.net.NetworkState;
import android.net.ISocketKeepaliveCallback;
import android.net.ProxyInfo;
import android.net.UidRange;
import android.os.Bundle;
import android.os.IBinder;
import android.os.INetworkActivityListener;
@@ -146,6 +147,7 @@ interface IConnectivityManager
    String getAlwaysOnVpnPackage(int userId);
    boolean isVpnLockdownEnabled(int userId);
    List<String> getVpnLockdownWhitelist(int userId);
    void setRequireVpnForUids(boolean requireVpn, in UidRange[] ranges);

    void setProvisioningNotificationVisible(boolean visible, int networkType, in String action);

+128 −68
Original line number Diff line number Diff line
@@ -545,6 +545,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
     */
    private static final int EVENT_CAPPORT_DATA_CHANGED = 46;

    /**
     * Used by setRequireVpnForUids.
     * arg1 = whether the specified UID ranges are required to use a VPN.
     * obj  = Array of UidRange objects.
     */
    private static final int EVENT_SET_REQUIRE_VPN_FOR_UIDS = 47;

    /**
     * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
     * should be shown.
@@ -1273,19 +1280,28 @@ public class ConnectivityService extends IConnectivityManager.Stub
        }
    }

    private Network[] getVpnUnderlyingNetworks(int uid) {
        synchronized (mVpns) {
            if (!mLockdownEnabled) {
                int user = UserHandle.getUserId(uid);
                Vpn vpn = mVpns.get(user);
                if (vpn != null && vpn.appliesToUid(uid)) {
                    return vpn.getUnderlyingNetworks();
    // TODO: determine what to do when more than one VPN applies to |uid|.
    private NetworkAgentInfo getVpnForUid(int uid) {
        synchronized (mNetworkForNetId) {
            for (int i = 0; i < mNetworkForNetId.size(); i++) {
                final NetworkAgentInfo nai = mNetworkForNetId.valueAt(i);
                if (nai.isVPN() && nai.everConnected && nai.networkCapabilities.appliesToUid(uid)) {
                    return nai;
                }
            }
        }
        return null;
    }

    private Network[] getVpnUnderlyingNetworks(int uid) {
        synchronized (mVpns) {
            if (mLockdownEnabled) return null;
        }
        final NetworkAgentInfo nai = getVpnForUid(uid);
        if (nai != null) return nai.declaredUnderlyingNetworks;
        return null;
    }

    private NetworkState getUnfilteredActiveNetworkState(int uid) {
        NetworkAgentInfo nai = getDefaultNetwork();

@@ -1311,7 +1327,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
    }

    /**
     * Check if UID should be blocked from using the network with the given LinkProperties.
     * Check if UID should be blocked from using the specified network.
     */
    private boolean isNetworkWithLinkPropertiesBlocked(LinkProperties lp, int uid,
            boolean ignoreBlocked) {
@@ -1319,12 +1335,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
        if (ignoreBlocked) {
            return false;
        }
        synchronized (mVpns) {
            final Vpn vpn = mVpns.get(UserHandle.getUserId(uid));
            if (vpn != null && vpn.getLockdown() && vpn.isBlockingUid(uid)) {
                return true;
            }
        }
        if (isUidBlockedByVpn(uid, mVpnBlockedUidRanges)) return true;
        final String iface = (lp == null ? "" : lp.getInterfaceName());
        return mPolicyManagerInternal.isUidNetworkingBlocked(uid, iface);
    }
@@ -1550,25 +1561,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
                            nc, mDeps.getCallingUid(), callingPackageName));
        }

        synchronized (mVpns) {
            if (!mLockdownEnabled) {
                Vpn vpn = mVpns.get(userId);
                if (vpn != null) {
                    Network[] networks = vpn.getUnderlyingNetworks();
        // No need to check mLockdownEnabled. If it's true, getVpnUnderlyingNetworks returns null.
        final Network[] networks = getVpnUnderlyingNetworks(Binder.getCallingUid());
        if (networks != null) {
            for (Network network : networks) {
                nc = getNetworkCapabilitiesInternal(network);
                if (nc != null) {
                                result.put(
                                        network,
                                        maybeSanitizeLocationInfoForCaller(
                    result.put(network, maybeSanitizeLocationInfoForCaller(
                                    nc, mDeps.getCallingUid(), callingPackageName));
                }
            }
        }
                }
            }
        }

        NetworkCapabilities[] out = new NetworkCapabilities[result.size()];
        out = result.values().toArray(out);
@@ -2011,29 +2014,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
    void handleRestrictBackgroundChanged(boolean restrictBackground) {
        if (mRestrictBackground == restrictBackground) return;

        final List<UidRange> blockedRanges = mVpnBlockedUidRanges;
        for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
            final boolean curMetered = nai.networkCapabilities.isMetered();
            maybeNotifyNetworkBlocked(nai, curMetered, curMetered, mRestrictBackground,
                    restrictBackground);
                    restrictBackground, blockedRanges, blockedRanges);
        }

        mRestrictBackground = restrictBackground;
    }

    private boolean isUidNetworkingWithVpnBlocked(int uid, int uidRules, boolean isNetworkMetered,
    private boolean isUidBlockedByRules(int uid, int uidRules, boolean isNetworkMetered,
            boolean isBackgroundRestricted) {
        synchronized (mVpns) {
            final Vpn vpn = mVpns.get(UserHandle.getUserId(uid));
            // Because the return value of this function depends on the list of UIDs the
            // always-on VPN blocks when in lockdown mode, when the always-on VPN changes that
            // list all state depending on the return value of this function has to be recomputed.
            // TODO: add a trigger when the always-on VPN sets its blocked UIDs to reevaluate and
            // send the necessary onBlockedStatusChanged callbacks.
            if (vpn != null && vpn.getLockdown() && vpn.isBlockingUid(uid)) {
                return true;
            }
        }

        return NetworkPolicyManagerInternal.isUidNetworkingBlocked(uid, uidRules,
                isNetworkMetered, isBackgroundRestricted);
    }
@@ -4308,6 +4300,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
                case EVENT_DATA_SAVER_CHANGED:
                    handleRestrictBackgroundChanged(toBool(msg.arg1));
                    break;
                case EVENT_SET_REQUIRE_VPN_FOR_UIDS:
                    handleSetRequireVpnForUids(toBool(msg.arg1), (UidRange[]) msg.obj);
                    break;
            }
        }
    }
@@ -4476,8 +4471,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
        if (!nai.everConnected) {
            return;
        }
        LinkProperties lp = getLinkProperties(nai);
        if (isNetworkWithLinkPropertiesBlocked(lp, uid, false)) {
        if (isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid, false)) {
            return;
        }
        nai.networkMonitor().forceReevaluation(uid);
@@ -4904,6 +4898,56 @@ public class ConnectivityService extends IConnectivityManager.Stub
        }
    }

    private boolean isUidBlockedByVpn(int uid, List<UidRange> blockedUidRanges) {
        // Determine whether this UID is blocked because of always-on VPN lockdown. If a VPN applies
        // to the UID, then the UID is not blocked because always-on VPN lockdown applies only when
        // a VPN is not up.
        final NetworkAgentInfo vpnNai = getVpnForUid(uid);
        if (vpnNai != null && !vpnNai.networkAgentConfig.allowBypass) return false;
        for (UidRange range : blockedUidRanges) {
            if (range.contains(uid)) return true;
        }
        return false;
    }

    @Override
    public void setRequireVpnForUids(boolean requireVpn, UidRange[] ranges) {
        NetworkStack.checkNetworkStackPermission(mContext);
        mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_REQUIRE_VPN_FOR_UIDS,
                encodeBool(requireVpn), 0 /* arg2 */, ranges));
    }

    private void handleSetRequireVpnForUids(boolean requireVpn, UidRange[] ranges) {
        if (DBG) {
            Log.d(TAG, "Setting VPN " + (requireVpn ? "" : "not ") + "required for UIDs: "
                    + Arrays.toString(ranges));
        }
        // Cannot use a Set since the list of UID ranges might contain duplicates.
        final List<UidRange> newVpnBlockedUidRanges = new ArrayList(mVpnBlockedUidRanges);
        for (int i = 0; i < ranges.length; i++) {
            if (requireVpn) {
                newVpnBlockedUidRanges.add(ranges[i]);
            } else {
                newVpnBlockedUidRanges.remove(ranges[i]);
            }
        }

        try {
            mNetd.networkRejectNonSecureVpn(requireVpn, toUidRangeStableParcels(ranges));
        } catch (RemoteException | ServiceSpecificException e) {
            Log.e(TAG, "setRequireVpnForUids(" + requireVpn + ", "
                    + Arrays.toString(ranges) + "): netd command failed: " + e);
        }

        for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
            final boolean curMetered = nai.networkCapabilities.isMetered();
            maybeNotifyNetworkBlocked(nai, curMetered, curMetered, mRestrictBackground,
                    mRestrictBackground, mVpnBlockedUidRanges, newVpnBlockedUidRanges);
        }

        mVpnBlockedUidRanges = newVpnBlockedUidRanges;
    }

    @Override
    public boolean updateLockdownVpn() {
        if (mDeps.getCallingUid() != Process.SYSTEM_UID) {
@@ -5889,6 +5933,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
    // NOTE: Only should be accessed on ConnectivityServiceThread, except dump().
    private final ArraySet<NetworkAgentInfo> mNetworkAgentInfos = new ArraySet<>();

    // UID ranges for users that are currently blocked by VPNs.
    // This array is accessed and iterated on multiple threads without holding locks, so its
    // contents must never be mutated. When the ranges change, the array is replaced with a new one
    // (on the handler thread).
    private volatile List<UidRange> mVpnBlockedUidRanges = new ArrayList<>();

    @GuardedBy("mBlockedAppUids")
    private final HashSet<Integer> mBlockedAppUids = new HashSet<>();

@@ -6543,7 +6593,7 @@ public class ConnectivityService extends IConnectivityManager.Stub

            if (meteredChanged) {
                maybeNotifyNetworkBlocked(nai, oldMetered, newMetered, mRestrictBackground,
                        mRestrictBackground);
                        mRestrictBackground, mVpnBlockedUidRanges, mVpnBlockedUidRanges);
            }

            final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING) !=
@@ -6608,6 +6658,15 @@ public class ConnectivityService extends IConnectivityManager.Stub
        return stableRanges;
    }

    private static UidRangeParcel[] toUidRangeStableParcels(UidRange[] ranges) {
        final UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.length];
        for (int i = 0; i < ranges.length; i++) {
            stableRanges[i] = new UidRangeParcel(ranges[i].start, ranges[i].stop);
        }
        return stableRanges;
    }


    private void updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc,
            NetworkCapabilities newNc) {
        Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUids();
@@ -7435,7 +7494,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
        }

        final boolean metered = nai.networkCapabilities.isMetered();
        final boolean blocked = isUidNetworkingWithVpnBlocked(nri.mUid, mUidRules.get(nri.mUid),
        boolean blocked;
        blocked = isUidBlockedByVpn(nri.mUid, mVpnBlockedUidRanges);
        blocked |= isUidBlockedByRules(nri.mUid, mUidRules.get(nri.mUid),
                metered, mRestrictBackground);
        callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, blocked ? 1 : 0);
    }
@@ -7457,21 +7518,25 @@ public class ConnectivityService extends IConnectivityManager.Stub
     * @param newRestrictBackground True if data saver is enabled.
     */
    private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered,
            boolean newMetered, boolean oldRestrictBackground, boolean newRestrictBackground) {
            boolean newMetered, boolean oldRestrictBackground, boolean newRestrictBackground,
            List<UidRange> oldBlockedUidRanges, List<UidRange> newBlockedUidRanges) {

        for (int i = 0; i < nai.numNetworkRequests(); i++) {
            NetworkRequest nr = nai.requestAt(i);
            NetworkRequestInfo nri = mNetworkRequests.get(nr);
            final int uidRules = mUidRules.get(nri.mUid);
            final boolean oldBlocked, newBlocked;
            // mVpns lock needs to be hold here to ensure that the active VPN cannot be changed
            // between these two calls.
            synchronized (mVpns) {
                oldBlocked = isUidNetworkingWithVpnBlocked(nri.mUid, uidRules, oldMetered,
            final boolean oldBlocked, newBlocked, oldVpnBlocked, newVpnBlocked;

            oldVpnBlocked = isUidBlockedByVpn(nri.mUid, oldBlockedUidRanges);
            newVpnBlocked = (oldBlockedUidRanges != newBlockedUidRanges)
                    ? isUidBlockedByVpn(nri.mUid, newBlockedUidRanges)
                    : oldVpnBlocked;

            oldBlocked = oldVpnBlocked || isUidBlockedByRules(nri.mUid, uidRules, oldMetered,
                    oldRestrictBackground);
                newBlocked = isUidNetworkingWithVpnBlocked(nri.mUid, uidRules, newMetered,
            newBlocked = newVpnBlocked || isUidBlockedByRules(nri.mUid, uidRules, newMetered,
                    newRestrictBackground);
            }

            if (oldBlocked != newBlocked) {
                callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
                        encodeBool(newBlocked));
@@ -7487,17 +7552,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
    private void maybeNotifyNetworkBlockedForNewUidRules(int uid, int newRules) {
        for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
            final boolean metered = nai.networkCapabilities.isMetered();
            final boolean vpnBlocked = isUidBlockedByVpn(uid, mVpnBlockedUidRanges);
            final boolean oldBlocked, newBlocked;
            // TODO: Consider that doze mode or turn on/off battery saver would deliver lots of uid
            // rules changed event. And this function actually loop through all connected nai and
            // its requests. It seems that mVpns lock will be grabbed frequently in this case.
            // Reduce the number of locking or optimize the use of lock are likely needed in future.
            synchronized (mVpns) {
                oldBlocked = isUidNetworkingWithVpnBlocked(
            oldBlocked = vpnBlocked || isUidBlockedByRules(
                    uid, mUidRules.get(uid), metered, mRestrictBackground);
                newBlocked = isUidNetworkingWithVpnBlocked(
            newBlocked = vpnBlocked || isUidBlockedByRules(
                    uid, newRules, metered, mRestrictBackground);
            }
            if (oldBlocked == newBlocked) {
                continue;
            }
+5 −1
Original line number Diff line number Diff line
@@ -146,7 +146,11 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
    // Underlying networks declared by the agent. Only set if supportsUnderlyingNetworks is true.
    // The networks in this list might be declared by a VPN app using setUnderlyingNetworks and are
    // not guaranteed to be current or correct, or even to exist.
    public @Nullable Network[] declaredUnderlyingNetworks;
    //
    // This array is read and iterated on multiple threads with no locking so its contents must
    // never be modified. When the list of networks changes, replace with a new array, on the
    // handler thread.
    public @Nullable volatile Network[] declaredUnderlyingNetworks;

    // The capabilities originally announced by the NetworkAgent, regardless of any capabilities
    // that were added or removed due to this network's underlying networks.
+28 −34
Original line number Diff line number Diff line
@@ -101,6 +101,7 @@ import android.security.KeyStore;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
import android.util.Range;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
@@ -223,7 +224,7 @@ public class Vpn {
    private @NonNull List<String> mLockdownAllowlist = Collections.emptyList();

     /**
     * A memory of what UIDs this class told netd to block for the lockdown feature.
     * A memory of what UIDs this class told ConnectivityService to block for the lockdown feature.
     *
     * Netd maintains ranges of UIDs for which network should be restricted to using only the VPN
     * for the lockdown feature. This class manages these UIDs and sends this information to netd.
@@ -237,7 +238,7 @@ public class Vpn {
     * @see mLockdown
     */
    @GuardedBy("this")
    private final Set<UidRangeParcel> mBlockedUidsAsToldToNetd = new ArraySet<>();
    private final Set<UidRangeParcel> mBlockedUidsAsToldToConnectivity = new ArraySet<>();

    // The user id of initiating VPN.
    private final int mUserId;
@@ -1588,7 +1589,7 @@ public class Vpn {
     *                {@link Vpn} goes through a VPN connection or is blocked until one is
     *                available, {@code false} to lift the requirement.
     *
     * @see #mBlockedUidsAsToldToNetd
     * @see #mBlockedUidsAsToldToConnectivity
     */
    @GuardedBy("this")
    private void setVpnForcedLocked(boolean enforce) {
@@ -1599,10 +1600,8 @@ public class Vpn {
            exemptedPackages = new ArrayList<>(mLockdownAllowlist);
            exemptedPackages.add(mPackage);
        }
        final Set<UidRangeParcel> rangesToTellNetdToRemove =
                new ArraySet<>(mBlockedUidsAsToldToNetd);

        final Set<UidRangeParcel> rangesToTellNetdToAdd;
        final Set<UidRangeParcel> rangesToRemove = new ArraySet<>(mBlockedUidsAsToldToConnectivity);
        final Set<UidRangeParcel> rangesToAdd;
        if (enforce) {
            final Set<UidRange> restrictedProfilesRanges =
                    createUserAndRestrictedProfilesRanges(mUserId,
@@ -1621,26 +1620,27 @@ public class Vpn {
                }
            }

            rangesToTellNetdToRemove.removeAll(rangesThatShouldBeBlocked);
            rangesToTellNetdToAdd = rangesThatShouldBeBlocked;
            // The ranges to tell netd to add are the ones that should be blocked minus the
            // ones it already knows to block. Note that this will change the contents of
            rangesToRemove.removeAll(rangesThatShouldBeBlocked);
            rangesToAdd = rangesThatShouldBeBlocked;
            // The ranges to tell ConnectivityService to add are the ones that should be blocked
            // minus the ones it already knows to block. Note that this will change the contents of
            // rangesThatShouldBeBlocked, but the list of ranges that should be blocked is
            // not used after this so it's fine to destroy it.
            rangesToTellNetdToAdd.removeAll(mBlockedUidsAsToldToNetd);
            rangesToAdd.removeAll(mBlockedUidsAsToldToConnectivity);
        } else {
            rangesToTellNetdToAdd = Collections.emptySet();
            rangesToAdd = Collections.emptySet();
        }

        // If mBlockedUidsAsToldToNetd used to be empty, this will always be a no-op.
        setAllowOnlyVpnForUids(false, rangesToTellNetdToRemove);
        setAllowOnlyVpnForUids(false, rangesToRemove);
        // If nothing should be blocked now, this will now be a no-op.
        setAllowOnlyVpnForUids(true, rangesToTellNetdToAdd);
        setAllowOnlyVpnForUids(true, rangesToAdd);
    }

    /**
     * Tell netd to add or remove a list of {@link UidRange}s to the list of UIDs that are only
     * allowed to make connections through sockets that have had {@code protect()} called on them.
     * Tell ConnectivityService to add or remove a list of {@link UidRange}s to the list of UIDs
     * that are only allowed to make connections through sockets that have had {@code protect()}
     * called on them.
     *
     * @param enforce {@code true} to add to the denylist, {@code false} to remove.
     * @param ranges {@link Collection} of {@link UidRange}s to add (if {@param enforce} is
@@ -1653,18 +1653,22 @@ public class Vpn {
        if (ranges.size() == 0) {
            return true;
        }
        final UidRangeParcel[] stableRanges = ranges.toArray(new UidRangeParcel[ranges.size()]);
        // Convert to Collection<Range> which is what the ConnectivityManager API takes.
        ArrayList<Range<Integer>> integerRanges = new ArrayList<>(ranges.size());
        for (UidRangeParcel uidRange : ranges) {
            integerRanges.add(new Range<>(uidRange.start, uidRange.stop));
        }
        try {
            mNetd.networkRejectNonSecureVpn(enforce, stableRanges);
        } catch (RemoteException | RuntimeException e) {
            mConnectivityManager.setRequireVpnForUids(enforce, integerRanges);
        } catch (RuntimeException e) {
            Log.e(TAG, "Updating blocked=" + enforce
                    + " for UIDs " + Arrays.toString(ranges.toArray()) + " failed", e);
            return false;
        }
        if (enforce) {
            mBlockedUidsAsToldToNetd.addAll(ranges);
            mBlockedUidsAsToldToConnectivity.addAll(ranges);
        } else {
            mBlockedUidsAsToldToNetd.removeAll(ranges);
            mBlockedUidsAsToldToConnectivity.removeAll(ranges);
        }
        return true;
    }
@@ -1783,9 +1787,6 @@ public class Vpn {

    /**
     * Updates underlying network set.
     *
     * <p>Note: Does not updates capabilities. Call {@link #updateCapabilities} from
     * ConnectivityService thread to get updated capabilities.
     */
    public synchronized boolean setUnderlyingNetworks(Network[] networks) {
        if (!isCallerEstablishedOwnerLocked()) {
@@ -1808,13 +1809,6 @@ public class Vpn {
        return true;
    }

    public synchronized Network[] getUnderlyingNetworks() {
        if (!isRunningLocked()) {
            return null;
        }
        return mConfig.underlyingNetworks;
    }

    /**
     * This method should only be called by ConnectivityService because it doesn't
     * have enough data to fill VpnInfo.primaryUnderlyingIface field.
@@ -1864,13 +1858,13 @@ public class Vpn {
     * the {@code uid}.
     *
     * @apiNote This method don't check VPN lockdown status.
     * @see #mBlockedUidsAsToldToNetd
     * @see #mBlockedUidsAsToldToConnectivity
     */
    public synchronized boolean isBlockingUid(int uid) {
        if (mNetworkInfo.isConnected()) {
            return !appliesToUid(uid);
        } else {
            return containsUid(mBlockedUidsAsToldToNetd, uid);
            return containsUid(mBlockedUidsAsToldToConnectivity, uid);
        }
    }

Loading