Loading services/core/java/com/android/server/connectivity/Vpn.java +65 −19 Original line number Diff line number Diff line Loading @@ -270,6 +270,13 @@ public class Vpn { @VisibleForTesting static final int DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT = 5 * 60; /** * Default keepalive value to consider long-lived TCP connections are expensive on the * VPN network from battery usage point of view. * TODO: consider reading from setting. */ @VisibleForTesting static final int DEFAULT_LONG_LIVED_TCP_CONNS_EXPENSIVE_TIMEOUT_SEC = 60; /** * Prefer using {@link IkeSessionParams.ESP_IP_VERSION_AUTO} and * {@link IkeSessionParams.ESP_ENCAP_TYPE_AUTO} for ESP packets. Loading Loading @@ -1670,9 +1677,12 @@ public class Vpn { capsBuilder.setUids(createUserAndRestrictedProfilesRanges(mUserId, mConfig.allowedApplications, mConfig.disallowedApplications)); capsBuilder.setTransportInfo( new VpnTransportInfo(getActiveVpnType(), mConfig.session, mConfig.allowBypass, false /* longLivedTcpConnectionsExpensive */)); final boolean expensive = areLongLivedTcpConnectionsExpensive(mVpnRunner); capsBuilder.setTransportInfo(new VpnTransportInfo( getActiveVpnType(), mConfig.session, mConfig.allowBypass, expensive)); // Only apps targeting Q and above can explicitly declare themselves as metered. // These VPNs are assumed metered unless they state otherwise. Loading Loading @@ -1704,6 +1714,17 @@ public class Vpn { updateState(DetailedState.CONNECTED, "agentConnect"); } private static boolean areLongLivedTcpConnectionsExpensive(@NonNull VpnRunner runner) { if (!(runner instanceof IkeV2VpnRunner)) return false; final int delay = ((IkeV2VpnRunner) runner).getOrGuessKeepaliveDelaySeconds(); return areLongLivedTcpConnectionsExpensive(delay); } private static boolean areLongLivedTcpConnectionsExpensive(int keepaliveDelaySec) { return keepaliveDelaySec < DEFAULT_LONG_LIVED_TCP_CONNS_EXPENSIVE_TIMEOUT_SEC; } private boolean canHaveRestrictedProfile(int userId) { final long token = Binder.clearCallingIdentity(); try { Loading Loading @@ -2988,10 +3009,8 @@ public class Vpn { // Ignore stale runner. if (mVpnRunner != Vpn.IkeV2VpnRunner.this) return; maybeMigrateIkeSession(mActiveNetwork); maybeMigrateIkeSessionAndUpdateVpnTransportInfo(mActiveNetwork); } // TODO: update the longLivedTcpConnectionsExpensive value in the // networkcapabilities of the VPN network. } }; Loading Loading @@ -3442,7 +3461,7 @@ public class Vpn { return; } if (maybeMigrateIkeSession(underlyingNetwork)) return; if (maybeMigrateIkeSessionAndUpdateVpnTransportInfo(underlyingNetwork)) return; startIkeSession(underlyingNetwork); } Loading Loading @@ -3549,7 +3568,43 @@ public class Vpn { return new CarrierConfigInfo(mccMnc, natKeepalive, encapType, ipVersion); } boolean maybeMigrateIkeSession(@NonNull Network underlyingNetwork) { private int getOrGuessKeepaliveDelaySeconds() { if (mProfile.isAutomaticNattKeepaliveTimerEnabled()) { return guessNattKeepaliveTimerForNetwork(); } else if (mProfile.getIkeTunnelConnectionParams() != null) { return mProfile.getIkeTunnelConnectionParams() .getIkeSessionParams().getNattKeepAliveDelaySeconds(); } return DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT; } boolean maybeMigrateIkeSessionAndUpdateVpnTransportInfo( @NonNull Network underlyingNetwork) { final int keepaliveDelaySec = getOrGuessKeepaliveDelaySeconds(); final boolean migrated = maybeMigrateIkeSession(underlyingNetwork, keepaliveDelaySec); if (migrated) { updateVpnTransportInfoAndNetCap(keepaliveDelaySec); } return migrated; } public void updateVpnTransportInfoAndNetCap(int keepaliveDelaySec) { final VpnTransportInfo info = new VpnTransportInfo( getActiveVpnType(), mConfig.session, mConfig.allowBypass, areLongLivedTcpConnectionsExpensive(keepaliveDelaySec)); final boolean ncUpdateRequired = !info.equals(mNetworkCapabilities.getTransportInfo()); if (ncUpdateRequired) { mNetworkCapabilities = new NetworkCapabilities.Builder(mNetworkCapabilities) .setTransportInfo(info) .build(); doSendNetworkCapabilities(mNetworkAgent, mNetworkCapabilities); } } private boolean maybeMigrateIkeSession(@NonNull Network underlyingNetwork, int keepaliveDelaySeconds) { if (mSession == null || !mMobikeEnabled) return false; // IKE session can schedule a migration event only when IKE AUTH is finished Loading @@ -3574,15 +3629,6 @@ public class Vpn { encapType = ESP_ENCAP_TYPE_AUTO; } final int keepaliveDelaySeconds; if (mProfile.isAutomaticNattKeepaliveTimerEnabled()) { keepaliveDelaySeconds = guessNattKeepaliveTimerForNetwork(); } else if (mProfile.getIkeTunnelConnectionParams() != null) { keepaliveDelaySeconds = mProfile.getIkeTunnelConnectionParams() .getIkeSessionParams().getNattKeepAliveDelaySeconds(); } else { keepaliveDelaySeconds = DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT; } mSession.setNetwork(underlyingNetwork, ipVersion, encapType, keepaliveDelaySeconds); return true; } Loading Loading @@ -3663,7 +3709,7 @@ public class Vpn { startOrMigrateIkeSession(mActiveNetwork); } else if (!nc.getSubscriptionIds().equals(oldNc.getSubscriptionIds())) { // Renew carrierConfig values. maybeMigrateIkeSession(mActiveNetwork); maybeMigrateIkeSessionAndUpdateVpnTransportInfo(mActiveNetwork); } } Loading Loading @@ -3691,7 +3737,7 @@ public class Vpn { Log.d(TAG, "Data stall suspected"); // Trigger MOBIKE. maybeMigrateIkeSession(mActiveNetwork); maybeMigrateIkeSessionAndUpdateVpnTransportInfo(mActiveNetwork); mDataStallSuspected = true; } } Loading Loading
services/core/java/com/android/server/connectivity/Vpn.java +65 −19 Original line number Diff line number Diff line Loading @@ -270,6 +270,13 @@ public class Vpn { @VisibleForTesting static final int DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT = 5 * 60; /** * Default keepalive value to consider long-lived TCP connections are expensive on the * VPN network from battery usage point of view. * TODO: consider reading from setting. */ @VisibleForTesting static final int DEFAULT_LONG_LIVED_TCP_CONNS_EXPENSIVE_TIMEOUT_SEC = 60; /** * Prefer using {@link IkeSessionParams.ESP_IP_VERSION_AUTO} and * {@link IkeSessionParams.ESP_ENCAP_TYPE_AUTO} for ESP packets. Loading Loading @@ -1670,9 +1677,12 @@ public class Vpn { capsBuilder.setUids(createUserAndRestrictedProfilesRanges(mUserId, mConfig.allowedApplications, mConfig.disallowedApplications)); capsBuilder.setTransportInfo( new VpnTransportInfo(getActiveVpnType(), mConfig.session, mConfig.allowBypass, false /* longLivedTcpConnectionsExpensive */)); final boolean expensive = areLongLivedTcpConnectionsExpensive(mVpnRunner); capsBuilder.setTransportInfo(new VpnTransportInfo( getActiveVpnType(), mConfig.session, mConfig.allowBypass, expensive)); // Only apps targeting Q and above can explicitly declare themselves as metered. // These VPNs are assumed metered unless they state otherwise. Loading Loading @@ -1704,6 +1714,17 @@ public class Vpn { updateState(DetailedState.CONNECTED, "agentConnect"); } private static boolean areLongLivedTcpConnectionsExpensive(@NonNull VpnRunner runner) { if (!(runner instanceof IkeV2VpnRunner)) return false; final int delay = ((IkeV2VpnRunner) runner).getOrGuessKeepaliveDelaySeconds(); return areLongLivedTcpConnectionsExpensive(delay); } private static boolean areLongLivedTcpConnectionsExpensive(int keepaliveDelaySec) { return keepaliveDelaySec < DEFAULT_LONG_LIVED_TCP_CONNS_EXPENSIVE_TIMEOUT_SEC; } private boolean canHaveRestrictedProfile(int userId) { final long token = Binder.clearCallingIdentity(); try { Loading Loading @@ -2988,10 +3009,8 @@ public class Vpn { // Ignore stale runner. if (mVpnRunner != Vpn.IkeV2VpnRunner.this) return; maybeMigrateIkeSession(mActiveNetwork); maybeMigrateIkeSessionAndUpdateVpnTransportInfo(mActiveNetwork); } // TODO: update the longLivedTcpConnectionsExpensive value in the // networkcapabilities of the VPN network. } }; Loading Loading @@ -3442,7 +3461,7 @@ public class Vpn { return; } if (maybeMigrateIkeSession(underlyingNetwork)) return; if (maybeMigrateIkeSessionAndUpdateVpnTransportInfo(underlyingNetwork)) return; startIkeSession(underlyingNetwork); } Loading Loading @@ -3549,7 +3568,43 @@ public class Vpn { return new CarrierConfigInfo(mccMnc, natKeepalive, encapType, ipVersion); } boolean maybeMigrateIkeSession(@NonNull Network underlyingNetwork) { private int getOrGuessKeepaliveDelaySeconds() { if (mProfile.isAutomaticNattKeepaliveTimerEnabled()) { return guessNattKeepaliveTimerForNetwork(); } else if (mProfile.getIkeTunnelConnectionParams() != null) { return mProfile.getIkeTunnelConnectionParams() .getIkeSessionParams().getNattKeepAliveDelaySeconds(); } return DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT; } boolean maybeMigrateIkeSessionAndUpdateVpnTransportInfo( @NonNull Network underlyingNetwork) { final int keepaliveDelaySec = getOrGuessKeepaliveDelaySeconds(); final boolean migrated = maybeMigrateIkeSession(underlyingNetwork, keepaliveDelaySec); if (migrated) { updateVpnTransportInfoAndNetCap(keepaliveDelaySec); } return migrated; } public void updateVpnTransportInfoAndNetCap(int keepaliveDelaySec) { final VpnTransportInfo info = new VpnTransportInfo( getActiveVpnType(), mConfig.session, mConfig.allowBypass, areLongLivedTcpConnectionsExpensive(keepaliveDelaySec)); final boolean ncUpdateRequired = !info.equals(mNetworkCapabilities.getTransportInfo()); if (ncUpdateRequired) { mNetworkCapabilities = new NetworkCapabilities.Builder(mNetworkCapabilities) .setTransportInfo(info) .build(); doSendNetworkCapabilities(mNetworkAgent, mNetworkCapabilities); } } private boolean maybeMigrateIkeSession(@NonNull Network underlyingNetwork, int keepaliveDelaySeconds) { if (mSession == null || !mMobikeEnabled) return false; // IKE session can schedule a migration event only when IKE AUTH is finished Loading @@ -3574,15 +3629,6 @@ public class Vpn { encapType = ESP_ENCAP_TYPE_AUTO; } final int keepaliveDelaySeconds; if (mProfile.isAutomaticNattKeepaliveTimerEnabled()) { keepaliveDelaySeconds = guessNattKeepaliveTimerForNetwork(); } else if (mProfile.getIkeTunnelConnectionParams() != null) { keepaliveDelaySeconds = mProfile.getIkeTunnelConnectionParams() .getIkeSessionParams().getNattKeepAliveDelaySeconds(); } else { keepaliveDelaySeconds = DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT; } mSession.setNetwork(underlyingNetwork, ipVersion, encapType, keepaliveDelaySeconds); return true; } Loading Loading @@ -3663,7 +3709,7 @@ public class Vpn { startOrMigrateIkeSession(mActiveNetwork); } else if (!nc.getSubscriptionIds().equals(oldNc.getSubscriptionIds())) { // Renew carrierConfig values. maybeMigrateIkeSession(mActiveNetwork); maybeMigrateIkeSessionAndUpdateVpnTransportInfo(mActiveNetwork); } } Loading Loading @@ -3691,7 +3737,7 @@ public class Vpn { Log.d(TAG, "Data stall suspected"); // Trigger MOBIKE. maybeMigrateIkeSession(mActiveNetwork); maybeMigrateIkeSessionAndUpdateVpnTransportInfo(mActiveNetwork); mDataStallSuspected = true; } } Loading