diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index e32ea8f7d5..a85f2e07ae 100755 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -10635,6 +10635,18 @@ public class ConnectivityService extends IConnectivityManager.Stub callback)); } + private boolean hasUnderlyingTestNetworks(NetworkCapabilities nc) { + final List underlyingNetworks = nc.getUnderlyingNetworks(); + if (underlyingNetworks == null) return false; + + for (Network network : underlyingNetworks) { + if (getNetworkCapabilitiesInternal(network).hasTransport(TRANSPORT_TEST)) { + return true; + } + } + return false; + } + @Override public void simulateDataStall(int detectionMethod, long timestampMillis, @NonNull Network network, @NonNull PersistableBundle extras) { @@ -10645,14 +10657,18 @@ public class ConnectivityService extends IConnectivityManager.Stub android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK); final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network); - if (!nc.hasTransport(TRANSPORT_TEST)) { - throw new SecurityException("Data Stall simulation is only possible for test networks"); + if (!nc.hasTransport(TRANSPORT_TEST) && !hasUnderlyingTestNetworks(nc)) { + throw new SecurityException( + "Data Stall simulation is only possible for test networks or networks built on" + + " top of test networks"); } final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); - if (nai == null || nai.creatorUid != mDeps.getCallingUid()) { - throw new SecurityException("Data Stall simulation is only possible for network " - + "creators"); + if (nai == null + || (nai.creatorUid != mDeps.getCallingUid() + && nai.creatorUid != Process.SYSTEM_UID)) { + throw new SecurityException( + "Data Stall simulation is only possible for network " + "creators"); } // Instead of passing the data stall directly to the ConnectivityDiagnostics handler, treat