Merge changes Ic490fee6,If78047c3 into main

* changes:
  Add hidden constants for communicating about local network agents
  Use isAtLeast* from deps
This commit is contained in:
Jean Chalard
2023-10-12 11:01:36 +00:00
committed by Gerrit Code Review
9 changed files with 120 additions and 7 deletions

View File

@@ -453,6 +453,7 @@ public final class NetworkCapabilities implements Parcelable {
NET_CAPABILITY_MMTEL, NET_CAPABILITY_MMTEL,
NET_CAPABILITY_PRIORITIZE_LATENCY, NET_CAPABILITY_PRIORITIZE_LATENCY,
NET_CAPABILITY_PRIORITIZE_BANDWIDTH, NET_CAPABILITY_PRIORITIZE_BANDWIDTH,
NET_CAPABILITY_LOCAL_NETWORK,
}) })
public @interface NetCapability { } public @interface NetCapability { }
@@ -714,7 +715,21 @@ public final class NetworkCapabilities implements Parcelable {
*/ */
public static final int NET_CAPABILITY_PRIORITIZE_BANDWIDTH = 35; public static final int NET_CAPABILITY_PRIORITIZE_BANDWIDTH = 35;
private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_PRIORITIZE_BANDWIDTH; /**
* This is a local network, e.g. a tethering downstream or a P2P direct network.
*
* <p>
* Note that local networks are not sent to callbacks by default. To receive callbacks about
* them, the {@link NetworkRequest} instance must be prepared to see them, either by
* adding the capability with {@link NetworkRequest.Builder#addCapability}, by removing
* this forbidden capability with {@link NetworkRequest.Builder#removeForbiddenCapability},
* or by clearing all capabilites with {@link NetworkRequest.Builder#clearCapabilities()}.
* </p>
* @hide
*/
public static final int NET_CAPABILITY_LOCAL_NETWORK = 36;
private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_LOCAL_NETWORK;
// Set all bits up to the MAX_NET_CAPABILITY-th bit // Set all bits up to the MAX_NET_CAPABILITY-th bit
private static final long ALL_VALID_CAPABILITIES = (2L << MAX_NET_CAPABILITY) - 1; private static final long ALL_VALID_CAPABILITIES = (2L << MAX_NET_CAPABILITY) - 1;
@@ -859,7 +874,7 @@ public final class NetworkCapabilities implements Parcelable {
} }
/** /**
* Removes (if found) the given forbidden capability from this {@code NetworkCapability} * Removes (if found) the given forbidden capability from this {@link NetworkCapabilities}
* instance that were added via addForbiddenCapability(int) or setCapabilities(int[], int[]). * instance that were added via addForbiddenCapability(int) or setCapabilities(int[], int[]).
* *
* @param capability the capability to be removed. * @param capability the capability to be removed.
@@ -872,6 +887,16 @@ public final class NetworkCapabilities implements Parcelable {
return this; return this;
} }
/**
* Removes all forbidden capabilities from this {@link NetworkCapabilities} instance.
* @return This NetworkCapabilities instance, to facilitate chaining.
* @hide
*/
public @NonNull NetworkCapabilities removeAllForbiddenCapabilities() {
mForbiddenNetworkCapabilities = 0;
return this;
}
/** /**
* Sets (or clears) the given capability on this {@link NetworkCapabilities} * Sets (or clears) the given capability on this {@link NetworkCapabilities}
* instance. * instance.
@@ -1039,11 +1064,12 @@ public final class NetworkCapabilities implements Parcelable {
} }
/** /**
* Check if this NetworkCapabilities has system managed capabilities or not. * Check if this NetworkCapabilities has connectivity-managed capabilities or not.
* @hide * @hide
*/ */
public boolean hasConnectivityManagedCapability() { public boolean hasConnectivityManagedCapability() {
return ((mNetworkCapabilities & CONNECTIVITY_MANAGED_CAPABILITIES) != 0); return (mNetworkCapabilities & CONNECTIVITY_MANAGED_CAPABILITIES) != 0
|| mForbiddenNetworkCapabilities != 0;
} }
/** /**
@@ -2523,6 +2549,7 @@ public final class NetworkCapabilities implements Parcelable {
case NET_CAPABILITY_MMTEL: return "MMTEL"; case NET_CAPABILITY_MMTEL: return "MMTEL";
case NET_CAPABILITY_PRIORITIZE_LATENCY: return "PRIORITIZE_LATENCY"; case NET_CAPABILITY_PRIORITIZE_LATENCY: return "PRIORITIZE_LATENCY";
case NET_CAPABILITY_PRIORITIZE_BANDWIDTH: return "PRIORITIZE_BANDWIDTH"; case NET_CAPABILITY_PRIORITIZE_BANDWIDTH: return "PRIORITIZE_BANDWIDTH";
case NET_CAPABILITY_LOCAL_NETWORK: return "LOCAL_NETWORK";
default: return Integer.toString(capability); default: return Integer.toString(capability);
} }
} }

View File

@@ -20,6 +20,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND; import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.NET_CAPABILITY_LOCAL_NETWORK;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; 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_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
@@ -283,6 +284,15 @@ public class NetworkRequest implements Parcelable {
NET_CAPABILITY_TRUSTED, NET_CAPABILITY_TRUSTED,
NET_CAPABILITY_VALIDATED); NET_CAPABILITY_VALIDATED);
/**
* Capabilities that are forbidden by default.
* Forbidden capabilities only make sense in NetworkRequest, not for network agents.
* Therefore these capabilities are only in NetworkRequest.
*/
private static final int[] DEFAULT_FORBIDDEN_CAPABILITIES = new int[] {
NET_CAPABILITY_LOCAL_NETWORK
};
private final NetworkCapabilities mNetworkCapabilities; private final NetworkCapabilities mNetworkCapabilities;
// A boolean that represents whether the NOT_VCN_MANAGED capability should be deduced when // A boolean that represents whether the NOT_VCN_MANAGED capability should be deduced when
@@ -298,6 +308,16 @@ public class NetworkRequest implements Parcelable {
// it for apps that do not have the NETWORK_SETTINGS permission. // it for apps that do not have the NETWORK_SETTINGS permission.
mNetworkCapabilities = new NetworkCapabilities(); mNetworkCapabilities = new NetworkCapabilities();
mNetworkCapabilities.setSingleUid(Process.myUid()); mNetworkCapabilities.setSingleUid(Process.myUid());
// Default forbidden capabilities are foremost meant to help with backward
// compatibility. When adding new types of network identified by a capability that
// might confuse older apps, a default forbidden capability will have apps not see
// these networks unless they explicitly ask for it.
// If the app called clearCapabilities() it will see everything, but then it
// can be argued that it's fair to send them too, since it asked for everything
// explicitly.
for (final int forbiddenCap : DEFAULT_FORBIDDEN_CAPABILITIES) {
mNetworkCapabilities.addForbiddenCapability(forbiddenCap);
}
} }
/** /**

View File

@@ -45,7 +45,8 @@ public final class NetworkScore implements Parcelable {
@IntDef(value = { @IntDef(value = {
KEEP_CONNECTED_NONE, KEEP_CONNECTED_NONE,
KEEP_CONNECTED_FOR_HANDOVER, KEEP_CONNECTED_FOR_HANDOVER,
KEEP_CONNECTED_FOR_TEST KEEP_CONNECTED_FOR_TEST,
KEEP_CONNECTED_DOWNSTREAM_NETWORK
}) })
public @interface KeepConnectedReason { } public @interface KeepConnectedReason { }
@@ -64,6 +65,12 @@ public final class NetworkScore implements Parcelable {
* @hide * @hide
*/ */
public static final int KEEP_CONNECTED_FOR_TEST = 2; public static final int KEEP_CONNECTED_FOR_TEST = 2;
/**
* Keep this network connected even if there is no outstanding request for it, because
* it is a downstream network.
* @hide
*/
public static final int KEEP_CONNECTED_DOWNSTREAM_NETWORK = 3;
// Agent-managed policies // Agent-managed policies
// This network should lose to a wifi that has ever been validated // This network should lose to a wifi that has ever been validated

View File

@@ -453,6 +453,8 @@ public class NetworkAgentInfo implements NetworkRanker.Scoreable {
* apply to the allowedUids field. * apply to the allowedUids field.
* They also should not mutate immutable capabilities, although for backward-compatibility * They also should not mutate immutable capabilities, although for backward-compatibility
* this is not enforced and limited to just a log. * this is not enforced and limited to just a log.
* Forbidden capabilities also make no sense for networks, so they are disallowed and
* will be ignored with a warning.
* *
* @param carrierPrivilegeAuthenticator the authenticator, to check access UIDs. * @param carrierPrivilegeAuthenticator the authenticator, to check access UIDs.
*/ */
@@ -461,6 +463,7 @@ public class NetworkAgentInfo implements NetworkRanker.Scoreable {
final NetworkCapabilities nc = new NetworkCapabilities(mDeclaredCapabilitiesUnsanitized); final NetworkCapabilities nc = new NetworkCapabilities(mDeclaredCapabilitiesUnsanitized);
if (nc.hasConnectivityManagedCapability()) { if (nc.hasConnectivityManagedCapability()) {
Log.wtf(TAG, "BUG: " + this + " has CS-managed capability."); Log.wtf(TAG, "BUG: " + this + " has CS-managed capability.");
nc.removeAllForbiddenCapabilities();
} }
if (networkCapabilities.getOwnerUid() != nc.getOwnerUid()) { if (networkCapabilities.getOwnerUid() != nc.getOwnerUid()) {
Log.e(TAG, toShortString() + ": ignoring attempt to change owner from " Log.e(TAG, toShortString() + ": ignoring attempt to change owner from "

View File

@@ -27,6 +27,9 @@ import org.junit.runners.model.Statement
@Deprecated("Use Build.VERSION_CODES", ReplaceWith("Build.VERSION_CODES.S_V2")) @Deprecated("Use Build.VERSION_CODES", ReplaceWith("Build.VERSION_CODES.S_V2"))
const val SC_V2 = Build.VERSION_CODES.S_V2 const val SC_V2 = Build.VERSION_CODES.S_V2
// TODO: Remove this when Build.VERSION_CODES.VANILLA_ICE_CREAM is available in all branches
// where this code builds
const val VANILLA_ICE_CREAM = 35 // Bui1ld.VERSION_CODES.VANILLA_ICE_CREAM
private val MAX_TARGET_SDK_ANNOTATION_RE = Pattern.compile("MaxTargetSdk([0-9]+)$") private val MAX_TARGET_SDK_ANNOTATION_RE = Pattern.compile("MaxTargetSdk([0-9]+)$")
private val targetSdk = InstrumentationRegistry.getContext().applicationInfo.targetSdkVersion private val targetSdk = InstrumentationRegistry.getContext().applicationInfo.targetSdkVersion

View File

@@ -26,6 +26,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_EIMS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE; import static android.net.NetworkCapabilities.NET_CAPABILITY_ENTERPRISE;
import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND; import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.NET_CAPABILITY_LOCAL_NETWORK;
import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS; import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
@@ -63,6 +64,7 @@ import static android.os.Process.INVALID_UID;
import static com.android.modules.utils.build.SdkLevel.isAtLeastR; import static com.android.modules.utils.build.SdkLevel.isAtLeastR;
import static com.android.modules.utils.build.SdkLevel.isAtLeastS; import static com.android.modules.utils.build.SdkLevel.isAtLeastS;
import static com.android.modules.utils.build.SdkLevel.isAtLeastT; import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
import static com.android.modules.utils.build.SdkLevel.isAtLeastV;
import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2; import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
import static com.android.testutils.MiscAsserts.assertEmpty; import static com.android.testutils.MiscAsserts.assertEmpty;
import static com.android.testutils.MiscAsserts.assertThrows; import static com.android.testutils.MiscAsserts.assertThrows;
@@ -369,6 +371,9 @@ public class NetworkCapabilitiesTest {
.addCapability(NET_CAPABILITY_INTERNET) .addCapability(NET_CAPABILITY_INTERNET)
.addCapability(NET_CAPABILITY_EIMS) .addCapability(NET_CAPABILITY_EIMS)
.addCapability(NET_CAPABILITY_NOT_METERED); .addCapability(NET_CAPABILITY_NOT_METERED);
if (isAtLeastV()) {
netCap.addCapability(NET_CAPABILITY_LOCAL_NETWORK);
}
if (isAtLeastS()) { if (isAtLeastS()) {
final ArraySet<Integer> allowedUids = new ArraySet<>(); final ArraySet<Integer> allowedUids = new ArraySet<>();
allowedUids.add(4); allowedUids.add(4);

View File

@@ -19,8 +19,10 @@ package android.net.cts;
import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA; import static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.NET_CAPABILITY_LOCAL_NETWORK;
import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS; import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL; import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL;
import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED; import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED;
import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH; import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH;
@@ -28,6 +30,8 @@ import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_VPN; import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static com.android.testutils.DevSdkIgnoreRuleKt.VANILLA_ICE_CREAM;
import static junit.framework.Assert.fail; import static junit.framework.Assert.fail;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
@@ -489,6 +493,32 @@ public class NetworkRequestTest {
assertArrayEquals(netCapabilities, nr.getCapabilities()); assertArrayEquals(netCapabilities, nr.getCapabilities());
} }
@Test @IgnoreUpTo(VANILLA_ICE_CREAM)
public void testDefaultCapabilities() {
final NetworkRequest defaultNR = new NetworkRequest.Builder().build();
assertTrue(defaultNR.hasForbiddenCapability(NET_CAPABILITY_LOCAL_NETWORK));
assertFalse(defaultNR.hasCapability(NET_CAPABILITY_LOCAL_NETWORK));
assertTrue(defaultNR.hasCapability(NET_CAPABILITY_NOT_VPN));
final NetworkCapabilities emptyNC =
NetworkCapabilities.Builder.withoutDefaultCapabilities().build();
assertFalse(defaultNR.canBeSatisfiedBy(emptyNC));
// defaultNC represent the capabilities of a network agent, so they must not contain
// forbidden capabilities by default.
final NetworkCapabilities defaultNC = new NetworkCapabilities.Builder().build();
assertArrayEquals(new int[0], defaultNC.getForbiddenCapabilities());
// A default NR can be satisfied by default NC.
assertTrue(defaultNR.canBeSatisfiedBy(defaultNC));
// Conversely, network requests have forbidden capabilities by default to manage
// backward compatibility, so test that these forbidden capabilities are in place.
// Starting in V, NET_CAPABILITY_LOCAL_NETWORK is introduced but is not seen by
// default, thanks to a default forbidden capability in NetworkRequest.
defaultNC.addCapability(NET_CAPABILITY_LOCAL_NETWORK);
assertFalse(defaultNR.canBeSatisfiedBy(defaultNC));
}
@Test @Test
public void testBuildRequestFromExistingRequestWithBuilder() { public void testBuildRequestFromExistingRequestWithBuilder() {
assumeTrue(TestUtils.shouldTestSApis()); assumeTrue(TestUtils.shouldTestSApis());

View File

@@ -16,8 +16,12 @@
package com.android.server package com.android.server
import android.net.NetworkCapabilities
import android.net.NetworkCapabilities.NET_CAPABILITY_LOCAL_NETWORK
import android.net.NetworkCapabilities.TRANSPORT_WIFI
import android.net.NetworkRequest import android.net.NetworkRequest
import android.net.NetworkScore import android.net.NetworkScore
import android.net.NetworkScore.KEEP_CONNECTED_DOWNSTREAM_NETWORK
import android.net.NetworkScore.KEEP_CONNECTED_FOR_TEST import android.net.NetworkScore.KEEP_CONNECTED_FOR_TEST
import android.os.Build import android.os.Build
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
@@ -32,6 +36,20 @@ import org.junit.runner.RunWith
@SmallTest @SmallTest
@IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
class CSKeepConnectedTest : CSTest() { class CSKeepConnectedTest : CSTest() {
@Test
fun testKeepConnectedLocalAgent() {
deps.setBuildSdk(VERSION_V)
val nc = NetworkCapabilities.Builder()
.addTransportType(TRANSPORT_WIFI)
.addCapability(NET_CAPABILITY_LOCAL_NETWORK)
.build()
val keepConnectedAgent = Agent(nc = nc, score = FromS(NetworkScore.Builder()
.setKeepConnectedReason(KEEP_CONNECTED_DOWNSTREAM_NETWORK)
.build()))
val dontKeepConnectedAgent = Agent(nc = nc)
doTestKeepConnected(keepConnectedAgent, dontKeepConnectedAgent)
}
@Test @Test
fun testKeepConnectedForTest() { fun testKeepConnectedForTest() {
val keepAgent = Agent(score = FromS(NetworkScore.Builder() val keepAgent = Agent(score = FromS(NetworkScore.Builder()

View File

@@ -98,7 +98,7 @@ class CSAgentWrapper(
nmCbCaptor.capture()) nmCbCaptor.capture())
// Create the actual agent. NetworkAgent is abstract, so make an anonymous subclass. // Create the actual agent. NetworkAgent is abstract, so make an anonymous subclass.
if (SdkLevel.isAtLeastS()) { if (deps.isAtLeastS()) {
agent = object : NetworkAgent(context, csHandlerThread.looper, TAG, agent = object : NetworkAgent(context, csHandlerThread.looper, TAG,
nc, lp, score.value, nac, provider) {} nc, lp, score.value, nac, provider) {}
} else { } else {
@@ -112,7 +112,7 @@ class CSAgentWrapper(
} }
private fun onValidationRequested() { private fun onValidationRequested() {
if (SdkLevel.isAtLeastT()) { if (deps.isAtLeastT()) {
verify(networkMonitor).notifyNetworkConnectedParcel(any()) verify(networkMonitor).notifyNetworkConnectedParcel(any())
} else { } else {
verify(networkMonitor).notifyNetworkConnected(any(), any()) verify(networkMonitor).notifyNetworkConnected(any(), any())