Update APIs that depends on isUidNetworkingBlocked to follow compat flag

NETWORKINFO_WITHOUT_INTERNET_BLOCKED compat flag only changed the
behavior of getActiveNetworkInfo that depends on
bpfNetMaps#isUidNetworkingBlocked.
But isUidNetworkingBlocked is used from other APIs(e.g. getActiveNetwork)
This CL update all APIs that depends on isUidNetworkingBlocked to follow
the compat flag to make behavior consistent between APIs.

aosp/3079290 will update onBlockedStatusChanged callback to follow this
compat flag.

Bug: 340773991
Bug: 339780435
Test: TH
Change-Id: If64ec800f21c2adc613884838202e2dece4a8d95
This commit is contained in:
Motomu Utsumi 2024-05-15 18:50:08 +09:00
commit b15be228d2
4 changed files with 35 additions and 25 deletions

View file

@ -100,23 +100,26 @@ public final class ConnectivityCompatChanges {
public static final long ENABLE_MATCH_LOCAL_NETWORK = 319212206L;
/**
* On Android {@link android.os.Build.VERSION_CODES.VANILLA_ICE_CREAM} or higher releases, when
* apps targeting Android {@link android.os.Build.VERSION_CODES.VANILLA_ICE_CREAM} or higher
* that do not have the {@link android.Manifest.permission#INTERNET} permission call
* {@link android.net.ConnectivityManager#getActiveNetworkInfo()}, the state of the returned
* {@link android.net.NetworkInfo} object will always be
* {@link android.net.NetworkInfo.DetailedState#BLOCKED}. This is because apps without the
* permission cannot access any network.
* On Android {@link android.os.Build.VERSION_CODES.VANILLA_ICE_CREAM} or higher releases,
* network access from apps targeting Android 36 or higher that do not have the
* {@link android.Manifest.permission#INTERNET} permission is considered blocked.
* This results in API behaviors change for apps without
* {@link android.Manifest.permission#INTERNET} permission.
* {@link android.net.NetworkInfo} returned from {@link android.net.ConnectivityManager} APIs
* always has {@link android.net.NetworkInfo.DetailedState#BLOCKED}.
* {@link android.net.ConnectivityManager#getActiveNetwork()} always returns null.
* {@link android.net.ConnectivityManager.NetworkCallback#onBlockedStatusChanged()} is always
* called with blocked=true.
* <p>
* For backwards compatibility, apps running on older releases, or targeting older SDK levels,
* will instead receive objects with the network's current state,
* such as {@link android.net.NetworkInfo.DetailedState#CONNECTED}.
* network access from apps without {@link android.Manifest.permission#INTERNET} permission is
* considered not blocked even though apps cannot access any networks.
*
* @hide
*/
@ChangeId
@EnabledAfter(targetSdkVersion = 35) // TODO: change to VANILLA_ICE_CREAM.
public static final long NETWORKINFO_WITHOUT_INTERNET_BLOCKED = 333340911L;
public static final long NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION = 333340911L;
private ConnectivityCompatChanges() {
}

View file

@ -102,7 +102,7 @@ import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST;
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST_ONLY;
import static android.net.connectivity.ConnectivityCompatChanges.ENABLE_MATCH_LOCAL_NETWORK;
import static android.net.connectivity.ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION;
import static android.net.connectivity.ConnectivityCompatChanges.NETWORKINFO_WITHOUT_INTERNET_BLOCKED;
import static android.net.connectivity.ConnectivityCompatChanges.NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION;
import static android.os.Process.INVALID_UID;
import static android.os.Process.VPN_UID;
import static android.system.OsConstants.ETH_P_ALL;
@ -2229,6 +2229,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
return nai;
}
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
private boolean hasInternetPermission(final int uid) {
return (mBpfNetMaps.getNetPermForUid(uid) & PERMISSION_INTERNET) != 0;
}
/**
* Check if UID should be blocked from using the specified network.
*/
@ -2243,8 +2248,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
try {
final boolean metered = nc == null ? true : nc.isMetered();
if (mDeps.isAtLeastV()) {
return mBpfNetMaps.isUidNetworkingBlocked(uid, metered)
|| (mBpfNetMaps.getNetPermForUid(uid) & PERMISSION_INTERNET) == 0;
final boolean hasInternetPermission = hasInternetPermission(uid);
final boolean blockedByUidRules = mBpfNetMaps.isUidNetworkingBlocked(uid, metered);
if (mDeps.isChangeEnabled(NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION, uid)) {
return blockedByUidRules || !hasInternetPermission;
} else {
return hasInternetPermission && blockedByUidRules;
}
} else {
return mPolicyManager.isUidNetworkingBlocked(uid, metered);
}
@ -2325,12 +2335,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
final int uid = mDeps.getCallingUid();
final NetworkAgentInfo nai = getNetworkAgentInfoForUid(uid);
if (nai == null) return null;
// Ignore blocked state to keep the backward compatibility if the compat flag is
// disabled and app does not have PERMISSION_INTERNET.
final boolean ignoreBlocked = mDeps.isAtLeastV()
&& !mDeps.isChangeEnabled(NETWORKINFO_WITHOUT_INTERNET_BLOCKED, uid)
&& (mBpfNetMaps.getNetPermForUid(uid) & PERMISSION_INTERNET) == 0;
final NetworkInfo networkInfo = getFilteredNetworkInfo(nai, uid, ignoreBlocked);
final NetworkInfo networkInfo = getFilteredNetworkInfo(nai, uid, false /* ignoreBlocked */);
maybeLogBlockedNetworkInfo(networkInfo, uid);
return networkInfo;
}

View file

@ -152,7 +152,7 @@ import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST_ONLY
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED;
import static android.net.Proxy.PROXY_CHANGE_ACTION;
import static android.net.RouteInfo.RTN_UNREACHABLE;
import static android.net.connectivity.ConnectivityCompatChanges.NETWORKINFO_WITHOUT_INTERNET_BLOCKED;
import static android.net.connectivity.ConnectivityCompatChanges.NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION;
import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED;
import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_REMOVED;
import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE;
@ -1948,7 +1948,8 @@ public class ConnectivityServiceTest {
setAlwaysOnNetworks(false);
setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com");
mDeps.setChangeIdEnabled(true, NETWORKINFO_WITHOUT_INTERNET_BLOCKED, Process.myUid());
mDeps.setChangeIdEnabled(
true, NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION, Process.myUid());
doReturn(PERMISSION_INTERNET).when(mBpfNetMaps).getNetPermForUid(anyInt());
// Note : Please do not add any new instrumentation here. If you need new instrumentation,
// please add it in CSTest and use subclasses of CSTest instead of adding more

View file

@ -24,7 +24,7 @@ import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED
import android.net.NetworkCapabilities.TRANSPORT_WIFI
import android.net.NetworkInfo.DetailedState.BLOCKED
import android.net.NetworkInfo.DetailedState.CONNECTED
import android.net.connectivity.ConnectivityCompatChanges.NETWORKINFO_WITHOUT_INTERNET_BLOCKED
import android.net.connectivity.ConnectivityCompatChanges.NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION
import android.os.Build
import androidx.test.filters.SmallTest
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
@ -53,7 +53,7 @@ class CSActiveNetworkInfoTest : CSTest() {
permissions: Int,
expectBlocked: Boolean
) {
deps.setChangeIdEnabled(changeEnabled, NETWORKINFO_WITHOUT_INTERNET_BLOCKED)
deps.setChangeIdEnabled(changeEnabled, NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION)
doReturn(permissions).`when`(bpfNetMaps).getNetPermForUid(anyInt())
val agent = Agent(nc = nc())
@ -66,6 +66,7 @@ class CSActiveNetworkInfoTest : CSTest() {
} else {
assertEquals(CONNECTED, networkInfo.detailedState)
}
assertEquals(expectBlocked, cm.activeNetwork == null)
agent.disconnect()
}
@ -82,8 +83,8 @@ class CSActiveNetworkInfoTest : CSTest() {
permissions = PERMISSION_INTERNET,
expectBlocked = true
)
// getActiveNetworkInfo does not return NetworkInfo with blocked state if the compat change
// is disabled and the app does not have PERMISSION_INTERNET
// Network access is considered not blocked if the compat change is disabled and an app
// does not have PERMISSION_INTERNET
doTestGetActiveNetworkInfo(
changeEnabled = false,
permissions = PERMISSION_NONE,