[BR03.1] Expose isUidNetworkingBlocked

Test: atest CtsHostsideNetworkTests:com.android.cts.net.HostsideNetworkCallbackTests
Bug: 297836825
Change-Id: I70b2351b9cd1c3c6fa34258397e0bf22cb8150b2
This commit is contained in:
Junyu Lai 2023-09-04 11:37:03 +08:00
commit bb59480733
5 changed files with 58 additions and 2 deletions

View file

@ -27,3 +27,10 @@ flag {
description: "Set data saver through ConnectivityManager API"
bug: "297836825"
}
flag {
name: "support_is_uid_networking_blocked"
namespace: "android_core_networking"
description: "This flag controls whether isUidNetworkingBlocked is supported"
bug: "297836825"
}

View file

@ -14,6 +14,7 @@ package android.net {
method @NonNull public static android.util.Range<java.lang.Integer> getIpSecNetIdRange();
method @Nullable @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public android.net.LinkProperties getRedactedLinkPropertiesForPackage(@NonNull android.net.LinkProperties, int, @NonNull String);
method @Nullable @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public android.net.NetworkCapabilities getRedactedNetworkCapabilitiesForPackage(@NonNull android.net.NetworkCapabilities, int, @NonNull String);
method @FlaggedApi("com.android.net.flags.support_is_uid_networking_blocked") @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public boolean isUidNetworkingBlocked(int, boolean);
method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerDefaultNetworkCallbackForUid(int, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void removeUidFromMeteredNetworkAllowList(int);

View file

@ -133,6 +133,8 @@ public class ConnectivityManager {
public static class Flags {
static final String SET_DATA_SAVER_VIA_CM =
"com.android.net.flags.set_data_saver_via_cm";
static final String SUPPORT_IS_UID_NETWORKING_BLOCKED =
"com.android.net.flags.support_is_uid_networking_blocked";
}
/**
@ -6311,8 +6313,8 @@ public class ConnectivityManager {
// is provided by linux file group permission AID_NET_BW_ACCT and the
// selinux context fs_bpf_net*.
// Only the system server process and the network stack have access.
// TODO: Expose api when ready.
// @SystemApi(client = MODULE_LIBRARIES)
@FlaggedApi(Flags.SUPPORT_IS_UID_NETWORKING_BLOCKED)
@SystemApi(client = MODULE_LIBRARIES)
@RequiresApi(Build.VERSION_CODES.TIRAMISU) // BPF maps were only mainlined in T
@RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
public boolean isUidNetworkingBlocked(int uid, boolean isNetworkMetered) {

View file

@ -37,6 +37,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.Instrumentation;
import android.app.NotificationManager;
@ -437,6 +438,42 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase {
+ maxTries + " attempts.\nLast error: " + error);
}
/**
* Asserts whether the network is blocked by accessing bpf maps if command-line tool supports.
*/
void assertNetworkAccessBlockedByBpf(boolean expectBlocked, int uid, boolean metered) {
final String result;
try {
result = executeShellCommand(
"cmd network_stack is-uid-networking-blocked " + uid + " " + metered);
} catch (AssertionError e) {
// If NetworkStack is too old to support this command, ignore and continue
// this test to verify other parts.
if (e.getMessage().contains("No shell command implementation.")) {
return;
}
throw e;
}
// Tethering module is too old.
if (result.contains("API is unsupported")) {
return;
}
assertEquals(expectBlocked, parseBooleanOrThrow(result.trim()));
}
/**
* Similar to {@link Boolean#parseBoolean} but throws when the input
* is unexpected instead of returning false.
*/
private static boolean parseBooleanOrThrow(@NonNull String s) {
// Don't use Boolean.parseBoolean
if ("true".equalsIgnoreCase(s)) return true;
if ("false".equalsIgnoreCase(s)) return false;
throw new IllegalArgumentException("Unexpected: " + s);
}
/**
* Checks whether the network is available as expected.
*

View file

@ -236,16 +236,19 @@ public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCa
// Enable restrict background
setRestrictBackground(true);
assertBackgroundNetworkAccess(false);
assertNetworkAccessBlockedByBpf(true, mUid, true /* metered */);
mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, true);
// Add to whitelist
addRestrictBackgroundWhitelist(mUid);
assertBackgroundNetworkAccess(true);
assertNetworkAccessBlockedByBpf(false, mUid, true /* metered */);
mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, false);
// Remove from whitelist
removeRestrictBackgroundWhitelist(mUid);
assertBackgroundNetworkAccess(false);
assertNetworkAccessBlockedByBpf(true, mUid, true /* metered */);
mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, true);
} finally {
mMeterednessConfiguration.resetNetworkMeteredness();
@ -257,11 +260,13 @@ public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCa
true /* hasCapability */, NET_CAPABILITY_NOT_METERED);
try {
assertBackgroundNetworkAccess(true);
assertNetworkAccessBlockedByBpf(false, mUid, false /* metered */);
mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, false);
// Disable restrict background, should not trigger callback
setRestrictBackground(false);
assertBackgroundNetworkAccess(true);
assertNetworkAccessBlockedByBpf(false, mUid, false /* metered */);
} finally {
mMeterednessConfiguration.resetNetworkMeteredness();
}
@ -275,11 +280,13 @@ public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCa
setBatterySaverMode(true);
assertBackgroundNetworkAccess(false);
mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, true);
assertNetworkAccessBlockedByBpf(true, mUid, true /* metered */);
// Disable Power Saver
setBatterySaverMode(false);
assertBackgroundNetworkAccess(true);
mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, false);
assertNetworkAccessBlockedByBpf(false, mUid, true /* metered */);
} finally {
mMeterednessConfiguration.resetNetworkMeteredness();
}
@ -293,11 +300,13 @@ public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCa
setBatterySaverMode(true);
assertBackgroundNetworkAccess(false);
mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, true);
assertNetworkAccessBlockedByBpf(true, mUid, false /* metered */);
// Disable Power Saver
setBatterySaverMode(false);
assertBackgroundNetworkAccess(true);
mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, false);
assertNetworkAccessBlockedByBpf(false, mUid, false /* metered */);
} finally {
mMeterednessConfiguration.resetNetworkMeteredness();
}