Loading services/core/java/com/android/server/connectivity/Vpn.java +16 −7 Original line number Diff line number Diff line Loading @@ -607,8 +607,9 @@ public class Vpn { * * <p>This method is only called when {@link collectVpnMetrics} is true. */ public VpnConnectivityMetrics makeVpnConnectivityMetrics(int userId) { return new VpnConnectivityMetrics(userId); public VpnConnectivityMetrics makeVpnConnectivityMetrics(int userId, ConnectivityManager cm) { return new VpnConnectivityMetrics(userId, cm); } } Loading Loading @@ -666,8 +667,8 @@ public class Vpn { mPackage = VpnConfig.LEGACY_VPN; mOwnerUID = getAppUid(mContext, mPackage, mUserId); mIsPackageTargetingAtLeastQ = doesPackageTargetAtLeastQ(mPackage); mVpnConnectivityMetrics = collectVpnMetrics() ? mDeps.makeVpnConnectivityMetrics(userId) : null; mVpnConnectivityMetrics = collectVpnMetrics() ? mDeps.makeVpnConnectivityMetrics(userId, mConnectivityManager) : null; try { netService.registerObserver(mObserver); Loading Loading @@ -2297,6 +2298,15 @@ public class Vpn { } } private void setUnderlyingNetworksAndMetrics(@NonNull Network[] networks) { synchronized (Vpn.this) { mConfig.underlyingNetworks = networks; if (mVpnConnectivityMetrics != null) { mVpnConnectivityMetrics.setUnderlyingNetwork(mConfig.underlyingNetworks); } } } /** * Updates underlying network set. */ Loading Loading @@ -3059,7 +3069,7 @@ public class Vpn { mConfig.dnsServers.clear(); mConfig.dnsServers.addAll(dnsAddrStrings); mConfig.underlyingNetworks = new Network[] {network}; setUnderlyingNetworksAndMetrics(new Network[] {network}); networkAgent = mNetworkAgent; Loading Loading @@ -3152,9 +3162,8 @@ public class Vpn { final LinkProperties oldLp = makeLinkProperties(); mConfig.underlyingNetworks = new Network[] {network}; setUnderlyingNetworksAndMetrics(new Network[] {network}); setMtu(calculateVpnMtu()); final LinkProperties newLp = makeLinkProperties(); // If MTU is < 1280, IPv6 addresses will be removed. If there are no addresses Loading services/core/java/com/android/server/connectivity/VpnConnectivityMetrics.java +54 −3 Original line number Diff line number Diff line Loading @@ -28,24 +28,32 @@ import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA512; import static android.net.IpSecAlgorithm.CRYPT_AES_CBC; import static android.net.IpSecAlgorithm.CRYPT_AES_CTR; import android.annotation.NonNull; import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkCapabilities; import android.net.VpnManager; import android.util.Log; import android.util.SparseArray; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import java.util.Arrays; import java.util.List; /** * Class to record the VpnConnectionReported into statsd. * Class to record the VpnConnectionReported into statsd, facilitating the logging of independent * VPN connection details per user. */ public class VpnConnectivityMetrics { private static final String TAG = VpnConnectivityMetrics.class.getSimpleName(); public static final int VPN_TYPE_UNKNOWN = 0; public static final int VPN_PROFILE_TYPE_UNKNOWN = 0; private static final int UNKNOWN_UNDERLYING_NETWORK_TYPE = -1; private static final SparseArray<String> sAlgorithms = new SparseArray<>(); private final int mUserId; @NonNull private final ConnectivityManager mConnectivityManager; private int mVpnType = VPN_TYPE_UNKNOWN; private int mVpnProfileType = VPN_PROFILE_TYPE_UNKNOWN; private int mMtu = 0; Loading @@ -56,6 +64,17 @@ public class VpnConnectivityMetrics { * index in {@code sAlgorithms} is considered allowed. */ private int mAllowedAlgorithms = 0; /** * An array representing the transport types of the underlying networks for the VPN. * Each element in this array corresponds to a specific underlying network. * The value of each element is the primary transport type of the network * (e.g., {@link NetworkCapabilities#TRANSPORT_WIFI}, * {@link NetworkCapabilities#TRANSPORT_CELLULAR}). * If the transport type of a network cannot be determined, the value will be * {@code UNKNOWN_UNDERLYING_NETWORK_TYPE}. */ @NonNull private int[] mUnderlyingNetworkTypes; // Static initializer block to populate the sAlgorithms mapping. It associates integer keys // (which also serve as bit positions for the mAllowedAlgorithms bitmask) with their Loading @@ -74,8 +93,9 @@ public class VpnConnectivityMetrics { sAlgorithms.put(10, CRYPT_AES_CTR); } public VpnConnectivityMetrics(int userId) { public VpnConnectivityMetrics(int userId, ConnectivityManager connectivityManager) { mUserId = userId; mConnectivityManager = connectivityManager; } /** Loading Loading @@ -146,4 +166,35 @@ public class VpnConnectivityMetrics { } return bitmask; } /** * Sets the transport types of the underlying networks for the VPN. * <p> * This method processes an array of {@link android.net.Network} objects. For each network, * it attempts to retrieve its {@link android.net.NetworkCapabilities} and extracts the * primary transport type (e.g., Wi-Fi, cellular). If capabilities cannot be retrieved * for a specific network, a predefined {@code UNKNOWN_UNDERLYING_NETWORK_TYPE} is * used for that entry. * * @param networks An array of {@link android.net.Network} objects representing the underlying * networks currently in use. */ public void setUnderlyingNetwork(@NonNull Network[] networks) { if (networks.length != 0) { int[] types = new int[networks.length]; for (int i = 0; i < networks.length; i++) { final NetworkCapabilities capabilities = mConnectivityManager.getNetworkCapabilities(networks[i]); if (capabilities != null) { // Get the primary transport type of the network. types[i] = capabilities.getTransportTypes()[0]; } else { types[i] = UNKNOWN_UNDERLYING_NETWORK_TYPE; } } mUnderlyingNetworkTypes = Arrays.copyOf(types, types.length); } else { mUnderlyingNetworkTypes = new int[0]; } } } services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java +2 −1 Original line number Diff line number Diff line Loading @@ -3293,7 +3293,8 @@ public class VpnTest extends VpnTestBase { } @Override public VpnConnectivityMetrics makeVpnConnectivityMetrics(int userId) { public VpnConnectivityMetrics makeVpnConnectivityMetrics(int userId, ConnectivityManager cm) { return mVpnConnectivityMetrics; } } Loading Loading
services/core/java/com/android/server/connectivity/Vpn.java +16 −7 Original line number Diff line number Diff line Loading @@ -607,8 +607,9 @@ public class Vpn { * * <p>This method is only called when {@link collectVpnMetrics} is true. */ public VpnConnectivityMetrics makeVpnConnectivityMetrics(int userId) { return new VpnConnectivityMetrics(userId); public VpnConnectivityMetrics makeVpnConnectivityMetrics(int userId, ConnectivityManager cm) { return new VpnConnectivityMetrics(userId, cm); } } Loading Loading @@ -666,8 +667,8 @@ public class Vpn { mPackage = VpnConfig.LEGACY_VPN; mOwnerUID = getAppUid(mContext, mPackage, mUserId); mIsPackageTargetingAtLeastQ = doesPackageTargetAtLeastQ(mPackage); mVpnConnectivityMetrics = collectVpnMetrics() ? mDeps.makeVpnConnectivityMetrics(userId) : null; mVpnConnectivityMetrics = collectVpnMetrics() ? mDeps.makeVpnConnectivityMetrics(userId, mConnectivityManager) : null; try { netService.registerObserver(mObserver); Loading Loading @@ -2297,6 +2298,15 @@ public class Vpn { } } private void setUnderlyingNetworksAndMetrics(@NonNull Network[] networks) { synchronized (Vpn.this) { mConfig.underlyingNetworks = networks; if (mVpnConnectivityMetrics != null) { mVpnConnectivityMetrics.setUnderlyingNetwork(mConfig.underlyingNetworks); } } } /** * Updates underlying network set. */ Loading Loading @@ -3059,7 +3069,7 @@ public class Vpn { mConfig.dnsServers.clear(); mConfig.dnsServers.addAll(dnsAddrStrings); mConfig.underlyingNetworks = new Network[] {network}; setUnderlyingNetworksAndMetrics(new Network[] {network}); networkAgent = mNetworkAgent; Loading Loading @@ -3152,9 +3162,8 @@ public class Vpn { final LinkProperties oldLp = makeLinkProperties(); mConfig.underlyingNetworks = new Network[] {network}; setUnderlyingNetworksAndMetrics(new Network[] {network}); setMtu(calculateVpnMtu()); final LinkProperties newLp = makeLinkProperties(); // If MTU is < 1280, IPv6 addresses will be removed. If there are no addresses Loading
services/core/java/com/android/server/connectivity/VpnConnectivityMetrics.java +54 −3 Original line number Diff line number Diff line Loading @@ -28,24 +28,32 @@ import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA512; import static android.net.IpSecAlgorithm.CRYPT_AES_CBC; import static android.net.IpSecAlgorithm.CRYPT_AES_CTR; import android.annotation.NonNull; import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkCapabilities; import android.net.VpnManager; import android.util.Log; import android.util.SparseArray; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import java.util.Arrays; import java.util.List; /** * Class to record the VpnConnectionReported into statsd. * Class to record the VpnConnectionReported into statsd, facilitating the logging of independent * VPN connection details per user. */ public class VpnConnectivityMetrics { private static final String TAG = VpnConnectivityMetrics.class.getSimpleName(); public static final int VPN_TYPE_UNKNOWN = 0; public static final int VPN_PROFILE_TYPE_UNKNOWN = 0; private static final int UNKNOWN_UNDERLYING_NETWORK_TYPE = -1; private static final SparseArray<String> sAlgorithms = new SparseArray<>(); private final int mUserId; @NonNull private final ConnectivityManager mConnectivityManager; private int mVpnType = VPN_TYPE_UNKNOWN; private int mVpnProfileType = VPN_PROFILE_TYPE_UNKNOWN; private int mMtu = 0; Loading @@ -56,6 +64,17 @@ public class VpnConnectivityMetrics { * index in {@code sAlgorithms} is considered allowed. */ private int mAllowedAlgorithms = 0; /** * An array representing the transport types of the underlying networks for the VPN. * Each element in this array corresponds to a specific underlying network. * The value of each element is the primary transport type of the network * (e.g., {@link NetworkCapabilities#TRANSPORT_WIFI}, * {@link NetworkCapabilities#TRANSPORT_CELLULAR}). * If the transport type of a network cannot be determined, the value will be * {@code UNKNOWN_UNDERLYING_NETWORK_TYPE}. */ @NonNull private int[] mUnderlyingNetworkTypes; // Static initializer block to populate the sAlgorithms mapping. It associates integer keys // (which also serve as bit positions for the mAllowedAlgorithms bitmask) with their Loading @@ -74,8 +93,9 @@ public class VpnConnectivityMetrics { sAlgorithms.put(10, CRYPT_AES_CTR); } public VpnConnectivityMetrics(int userId) { public VpnConnectivityMetrics(int userId, ConnectivityManager connectivityManager) { mUserId = userId; mConnectivityManager = connectivityManager; } /** Loading Loading @@ -146,4 +166,35 @@ public class VpnConnectivityMetrics { } return bitmask; } /** * Sets the transport types of the underlying networks for the VPN. * <p> * This method processes an array of {@link android.net.Network} objects. For each network, * it attempts to retrieve its {@link android.net.NetworkCapabilities} and extracts the * primary transport type (e.g., Wi-Fi, cellular). If capabilities cannot be retrieved * for a specific network, a predefined {@code UNKNOWN_UNDERLYING_NETWORK_TYPE} is * used for that entry. * * @param networks An array of {@link android.net.Network} objects representing the underlying * networks currently in use. */ public void setUnderlyingNetwork(@NonNull Network[] networks) { if (networks.length != 0) { int[] types = new int[networks.length]; for (int i = 0; i < networks.length; i++) { final NetworkCapabilities capabilities = mConnectivityManager.getNetworkCapabilities(networks[i]); if (capabilities != null) { // Get the primary transport type of the network. types[i] = capabilities.getTransportTypes()[0]; } else { types[i] = UNKNOWN_UNDERLYING_NETWORK_TYPE; } } mUnderlyingNetworkTypes = Arrays.copyOf(types, types.length); } else { mUnderlyingNetworkTypes = new int[0]; } } }
services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java +2 −1 Original line number Diff line number Diff line Loading @@ -3293,7 +3293,8 @@ public class VpnTest extends VpnTestBase { } @Override public VpnConnectivityMetrics makeVpnConnectivityMetrics(int userId) { public VpnConnectivityMetrics makeVpnConnectivityMetrics(int userId, ConnectivityManager cm) { return mVpnConnectivityMetrics; } } Loading