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
diff --git a/framework/src/android/net/connectivity/ConnectivityCompatChanges.java b/framework/src/android/net/connectivity/ConnectivityCompatChanges.java
index 8701851..02ef8b7 100644
--- a/framework/src/android/net/connectivity/ConnectivityCompatChanges.java
+++ b/framework/src/android/net/connectivity/ConnectivityCompatChanges.java
@@ -100,23 +100,26 @@
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() {
}
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 46bd9bc..39ea286 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -102,7 +102,7 @@
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 @@
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 @@
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 @@
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;
}
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index 717c5a1..b6cb09b 100755
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -152,7 +152,7 @@
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 @@
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
diff --git a/tests/unit/java/com/android/server/connectivityservice/CSActiveNetworkInfoTest.kt b/tests/unit/java/com/android/server/connectivityservice/CSActiveNetworkInfoTest.kt
index 1891a78..360a298 100644
--- a/tests/unit/java/com/android/server/connectivityservice/CSActiveNetworkInfoTest.kt
+++ b/tests/unit/java/com/android/server/connectivityservice/CSActiveNetworkInfoTest.kt
@@ -24,7 +24,7 @@
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 @@
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 @@
} else {
assertEquals(CONNECTED, networkInfo.detailedState)
}
+ assertEquals(expectBlocked, cm.activeNetwork == null)
agent.disconnect()
}
@@ -82,8 +83,8 @@
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,