Snap for 6520394 from 535e4abdd2ff2f2c5547de6f8b690e2b09623bb7 to rvc-release
Change-Id: I3a9781147617a602c1f75f5327f232d11d010b7c
This commit is contained in:
@@ -3087,23 +3087,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
|
||||
@Override
|
||||
public void notifyDataStallSuspected(DataStallReportParcelable p) {
|
||||
final PersistableBundle extras = new PersistableBundle();
|
||||
switch (p.detectionMethod) {
|
||||
case DETECTION_METHOD_DNS_EVENTS:
|
||||
extras.putInt(KEY_DNS_CONSECUTIVE_TIMEOUTS, p.dnsConsecutiveTimeouts);
|
||||
break;
|
||||
case DETECTION_METHOD_TCP_METRICS:
|
||||
extras.putInt(KEY_TCP_PACKET_FAIL_RATE, p.tcpPacketFailRate);
|
||||
extras.putInt(KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS,
|
||||
p.tcpMetricsCollectionPeriodMillis);
|
||||
break;
|
||||
default:
|
||||
log("Unknown data stall detection method, ignoring: " + p.detectionMethod);
|
||||
return;
|
||||
}
|
||||
|
||||
proxyDataStallToConnectivityDiagnosticsHandler(
|
||||
p.detectionMethod, mNetId, p.timestampMillis, extras);
|
||||
ConnectivityService.this.notifyDataStallSuspected(p, mNetId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3117,11 +3101,31 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
private void proxyDataStallToConnectivityDiagnosticsHandler(int detectionMethod, int netId,
|
||||
long timestampMillis, @NonNull PersistableBundle extras) {
|
||||
private void notifyDataStallSuspected(DataStallReportParcelable p, int netId) {
|
||||
final PersistableBundle extras = new PersistableBundle();
|
||||
switch (p.detectionMethod) {
|
||||
case DETECTION_METHOD_DNS_EVENTS:
|
||||
extras.putInt(KEY_DNS_CONSECUTIVE_TIMEOUTS, p.dnsConsecutiveTimeouts);
|
||||
break;
|
||||
case DETECTION_METHOD_TCP_METRICS:
|
||||
extras.putInt(KEY_TCP_PACKET_FAIL_RATE, p.tcpPacketFailRate);
|
||||
extras.putInt(KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS,
|
||||
p.tcpMetricsCollectionPeriodMillis);
|
||||
break;
|
||||
default:
|
||||
// TODO(b/156294356): update for new data stall detection methods
|
||||
log("Unknown data stall detection method, ignoring: " + p.detectionMethod);
|
||||
return;
|
||||
}
|
||||
|
||||
notifyDataStallSuspected(p.detectionMethod, netId, p.timestampMillis, extras);
|
||||
}
|
||||
|
||||
private void notifyDataStallSuspected(int detectionMethod, int netId, long timestampMillis,
|
||||
@NonNull PersistableBundle extras) {
|
||||
final Message msg = mConnectivityDiagnosticsHandler.obtainMessage(
|
||||
ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED,
|
||||
detectionMethod, netId, timestampMillis);
|
||||
ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED, detectionMethod, netId,
|
||||
timestampMillis);
|
||||
msg.setData(new Bundle(extras));
|
||||
|
||||
// NetworkStateTrackerHandler currently doesn't take any actions based on data
|
||||
@@ -7134,6 +7138,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND);
|
||||
|
||||
if (!createNativeNetwork(networkAgent)) return;
|
||||
if (networkAgent.isVPN()) {
|
||||
// Initialize the VPN capabilities to their starting values according to the
|
||||
// underlying networks. This will avoid a spurious callback to
|
||||
// onCapabilitiesUpdated being sent in updateAllVpnCapabilities below as
|
||||
// the VPN would switch from its default, blank capabilities to those
|
||||
// that reflect the capabilities of its underlying networks.
|
||||
updateAllVpnsCapabilities();
|
||||
}
|
||||
networkAgent.created = true;
|
||||
}
|
||||
|
||||
@@ -8177,7 +8189,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
+ "creators");
|
||||
}
|
||||
|
||||
proxyDataStallToConnectivityDiagnosticsHandler(
|
||||
detectionMethod, network.netId, timestampMillis, extras);
|
||||
notifyDataStallSuspected(detectionMethod, network.netId, timestampMillis, extras);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,9 @@ public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork {
|
||||
break;
|
||||
case TRANSPORT_VPN:
|
||||
mNetworkCapabilities.removeCapability(NET_CAPABILITY_NOT_VPN);
|
||||
// VPNs deduce the SUSPENDED capability from their underlying networks and there
|
||||
// is no public API to let VPN services set it.
|
||||
mNetworkCapabilities.removeCapability(NET_CAPABILITY_NOT_SUSPENDED);
|
||||
mScore = ConnectivityConstants.VPN_DEFAULT_SCORE;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -5387,8 +5387,6 @@ public class ConnectivityServiceTest {
|
||||
|
||||
// Even though the VPN is unvalidated, it becomes the default network for our app.
|
||||
callback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent);
|
||||
// TODO: this looks like a spurious callback.
|
||||
callback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, vpnNetworkAgent);
|
||||
callback.assertNoCallback();
|
||||
|
||||
assertTrue(vpnNetworkAgent.getScore() > mEthernetNetworkAgent.getScore());
|
||||
@@ -5417,6 +5415,47 @@ public class ConnectivityServiceTest {
|
||||
callback.expectAvailableCallbacksValidated(mEthernetNetworkAgent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVpnStartsWithUnderlyingCaps() throws Exception {
|
||||
final int uid = Process.myUid();
|
||||
|
||||
final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback();
|
||||
final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder()
|
||||
.removeCapability(NET_CAPABILITY_NOT_VPN)
|
||||
.addTransportType(TRANSPORT_VPN)
|
||||
.build();
|
||||
mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback);
|
||||
vpnNetworkCallback.assertNoCallback();
|
||||
|
||||
// Connect cell. It will become the default network, and in the absence of setting
|
||||
// underlying networks explicitly it will become the sole underlying network for the vpn.
|
||||
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
|
||||
mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
|
||||
mCellNetworkAgent.connect(true);
|
||||
|
||||
final TestNetworkAgentWrapper vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN);
|
||||
final ArraySet<UidRange> ranges = new ArraySet<>();
|
||||
ranges.add(new UidRange(uid, uid));
|
||||
mMockVpn.setNetworkAgent(vpnNetworkAgent);
|
||||
mMockVpn.connect();
|
||||
mMockVpn.setUids(ranges);
|
||||
vpnNetworkAgent.connect(true /* validated */, false /* hasInternet */,
|
||||
false /* isStrictMode */);
|
||||
|
||||
vpnNetworkCallback.expectAvailableCallbacks(vpnNetworkAgent.getNetwork(),
|
||||
false /* suspended */, false /* validated */, false /* blocked */, TIMEOUT_MS);
|
||||
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent.getNetwork(), TIMEOUT_MS,
|
||||
nc -> nc.hasCapability(NET_CAPABILITY_VALIDATED));
|
||||
|
||||
final NetworkCapabilities nc = mCm.getNetworkCapabilities(vpnNetworkAgent.getNetwork());
|
||||
assertTrue(nc.hasTransport(TRANSPORT_VPN));
|
||||
assertTrue(nc.hasTransport(TRANSPORT_CELLULAR));
|
||||
assertFalse(nc.hasTransport(TRANSPORT_WIFI));
|
||||
assertTrue(nc.hasCapability(NET_CAPABILITY_VALIDATED));
|
||||
assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED));
|
||||
assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVpnSetUnderlyingNetworks() throws Exception {
|
||||
final int uid = Process.myUid();
|
||||
@@ -5447,9 +5486,12 @@ public class ConnectivityServiceTest {
|
||||
assertFalse(nc.hasTransport(TRANSPORT_WIFI));
|
||||
// For safety reasons a VPN without underlying networks is considered metered.
|
||||
assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED));
|
||||
// A VPN without underlying networks is not suspended.
|
||||
assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
|
||||
|
||||
// Connect cell and use it as an underlying network.
|
||||
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
|
||||
mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
|
||||
mCellNetworkAgent.connect(true);
|
||||
|
||||
mService.setUnderlyingNetworksForVpn(
|
||||
@@ -5458,10 +5500,12 @@ public class ConnectivityServiceTest {
|
||||
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
|
||||
(caps) -> caps.hasTransport(TRANSPORT_VPN)
|
||||
&& caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
|
||||
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED));
|
||||
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
|
||||
&& caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
|
||||
|
||||
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
|
||||
mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
|
||||
mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
|
||||
mWiFiNetworkAgent.connect(true);
|
||||
|
||||
mService.setUnderlyingNetworksForVpn(
|
||||
@@ -5470,7 +5514,8 @@ public class ConnectivityServiceTest {
|
||||
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
|
||||
(caps) -> caps.hasTransport(TRANSPORT_VPN)
|
||||
&& caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI)
|
||||
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED));
|
||||
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
|
||||
&& caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
|
||||
|
||||
// Don't disconnect, but note the VPN is not using wifi any more.
|
||||
mService.setUnderlyingNetworksForVpn(
|
||||
@@ -5479,16 +5524,36 @@ public class ConnectivityServiceTest {
|
||||
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
|
||||
(caps) -> caps.hasTransport(TRANSPORT_VPN)
|
||||
&& caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
|
||||
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED));
|
||||
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
|
||||
&& caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
|
||||
|
||||
// Use Wifi but not cell. Note the VPN is now unmetered.
|
||||
// Remove NOT_SUSPENDED from the only network and observe VPN is now suspended.
|
||||
mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED);
|
||||
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
|
||||
(caps) -> caps.hasTransport(TRANSPORT_VPN)
|
||||
&& caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
|
||||
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
|
||||
&& !caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
|
||||
vpnNetworkCallback.expectCallback(CallbackEntry.SUSPENDED, vpnNetworkAgent);
|
||||
|
||||
// Add NOT_SUSPENDED again and observe VPN is no longer suspended.
|
||||
mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
|
||||
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
|
||||
(caps) -> caps.hasTransport(TRANSPORT_VPN)
|
||||
&& caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
|
||||
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
|
||||
&& caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
|
||||
vpnNetworkCallback.expectCallback(CallbackEntry.RESUMED, vpnNetworkAgent);
|
||||
|
||||
// Use Wifi but not cell. Note the VPN is now unmetered and not suspended.
|
||||
mService.setUnderlyingNetworksForVpn(
|
||||
new Network[] { mWiFiNetworkAgent.getNetwork() });
|
||||
|
||||
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
|
||||
(caps) -> caps.hasTransport(TRANSPORT_VPN)
|
||||
&& !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI)
|
||||
&& caps.hasCapability(NET_CAPABILITY_NOT_METERED));
|
||||
&& caps.hasCapability(NET_CAPABILITY_NOT_METERED)
|
||||
&& caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
|
||||
|
||||
// Use both again.
|
||||
mService.setUnderlyingNetworksForVpn(
|
||||
@@ -5497,7 +5562,37 @@ public class ConnectivityServiceTest {
|
||||
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
|
||||
(caps) -> caps.hasTransport(TRANSPORT_VPN)
|
||||
&& caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI)
|
||||
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED));
|
||||
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
|
||||
&& caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
|
||||
|
||||
// Cell is suspended again. As WiFi is not, this should not cause a callback.
|
||||
mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED);
|
||||
vpnNetworkCallback.assertNoCallback();
|
||||
|
||||
// Stop using WiFi. The VPN is suspended again.
|
||||
mService.setUnderlyingNetworksForVpn(
|
||||
new Network[] { mCellNetworkAgent.getNetwork() });
|
||||
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
|
||||
(caps) -> caps.hasTransport(TRANSPORT_VPN)
|
||||
&& caps.hasTransport(TRANSPORT_CELLULAR)
|
||||
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
|
||||
&& !caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
|
||||
// While the SUSPENDED callback should in theory be sent here, it is not. This is
|
||||
// a bug in ConnectivityService, but as the SUSPENDED and RESUMED callbacks have never
|
||||
// been public and are deprecated and slated for removal, there is no sense in spending
|
||||
// resources fixing this bug now.
|
||||
|
||||
// Use both again.
|
||||
mService.setUnderlyingNetworksForVpn(
|
||||
new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() });
|
||||
|
||||
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
|
||||
(caps) -> caps.hasTransport(TRANSPORT_VPN)
|
||||
&& caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI)
|
||||
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
|
||||
&& caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
|
||||
// As above, the RESUMED callback not being sent here is a bug, but not a bug that's
|
||||
// worth anybody's time to fix.
|
||||
|
||||
// Disconnect cell. Receive update without even removing the dead network from the
|
||||
// underlying networks – it's dead anyway. Not metered any more.
|
||||
|
||||
@@ -25,6 +25,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||
@@ -606,6 +607,7 @@ public class VpnTest {
|
||||
.addCapability(NET_CAPABILITY_NOT_METERED)
|
||||
.addCapability(NET_CAPABILITY_NOT_ROAMING)
|
||||
.addCapability(NET_CAPABILITY_NOT_CONGESTED)
|
||||
.addCapability(NET_CAPABILITY_NOT_SUSPENDED)
|
||||
.setLinkUpstreamBandwidthKbps(20));
|
||||
setMockedNetworks(networks);
|
||||
|
||||
@@ -621,6 +623,7 @@ public class VpnTest {
|
||||
assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED));
|
||||
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
|
||||
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED));
|
||||
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
|
||||
|
||||
Vpn.applyUnderlyingCapabilities(
|
||||
mConnectivityManager,
|
||||
@@ -635,6 +638,7 @@ public class VpnTest {
|
||||
assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED));
|
||||
assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
|
||||
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED));
|
||||
assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
|
||||
|
||||
Vpn.applyUnderlyingCapabilities(
|
||||
mConnectivityManager, new Network[] {wifi}, caps, false /* isAlwaysMetered */);
|
||||
@@ -646,6 +650,7 @@ public class VpnTest {
|
||||
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_METERED));
|
||||
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
|
||||
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED));
|
||||
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
|
||||
|
||||
Vpn.applyUnderlyingCapabilities(
|
||||
mConnectivityManager, new Network[] {wifi}, caps, true /* isAlwaysMetered */);
|
||||
@@ -657,6 +662,7 @@ public class VpnTest {
|
||||
assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED));
|
||||
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
|
||||
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED));
|
||||
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
|
||||
|
||||
Vpn.applyUnderlyingCapabilities(
|
||||
mConnectivityManager,
|
||||
@@ -671,6 +677,7 @@ public class VpnTest {
|
||||
assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED));
|
||||
assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
|
||||
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED));
|
||||
assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user