Merge "Add MatchNonThreadLocalNetworks flag in NetworkCapabilities" into main

This commit is contained in:
Treehugger Robot 2025-03-20 21:14:39 -07:00 • committed by Gerrit Code Review
commit 95af095af9
2 changed files with 145 additions and 5 deletions

View file

@ -360,6 +360,8 @@ public final class NetworkCapabilities implements Parcelable {
mUnderlyingNetworks = null;
mEnterpriseId = 0;
mReservationId = RES_ID_UNSET;
// TODO: Change to default disabled when introduce this filtering.
mMatchNonThreadLocalNetworks = true;
}
/**
@ -395,6 +397,7 @@ public final class NetworkCapabilities implements Parcelable {
mUnderlyingNetworks = nc.mUnderlyingNetworks;
mEnterpriseId = nc.mEnterpriseId;
mReservationId = nc.mReservationId;
mMatchNonThreadLocalNetworks = nc.mMatchNonThreadLocalNetworks;
}
/**
@ -2236,7 +2239,8 @@ public final class NetworkCapabilities implements Parcelable {
&& (onlyImmutable || satisfiedBySSID(nc))
&& (onlyImmutable || satisfiedByRequestor(nc))
&& (onlyImmutable || satisfiedBySubscriptionIds(nc)))
&& satisfiedByReservationId(nc);
&& satisfiedByReservationId(nc)
&& satisfiedByMatchNonThreadLocalNetworks(nc);
}
/**
@ -2351,7 +2355,8 @@ public final class NetworkCapabilities implements Parcelable {
&& equalsSubscriptionIds(that)
&& equalsUnderlyingNetworks(that)
&& equalsEnterpriseCapabilitiesId(that)
&& equalsReservationId(that);
&& equalsReservationId(that)
&& equalsMatchNonThreadLocalNetworks(that);
}
@Override
@ -2371,15 +2376,15 @@ public final class NetworkCapabilities implements Parcelable {
+ Objects.hashCode(mAllowedUids) * 41
+ Objects.hashCode(mSSID) * 43
+ Objects.hashCode(mTransportInfo) * 47
+ Objects.hashCode(mPrivateDnsBroken) * 53
+ Boolean.hashCode(mPrivateDnsBroken) * 53
+ Objects.hashCode(mRequestorUid) * 59
+ Objects.hashCode(mRequestorPackageName) * 61
+ Arrays.hashCode(mAdministratorUids) * 67
+ Objects.hashCode(mSubIds) * 71
+ Objects.hashCode(mUnderlyingNetworks) * 73
+ mEnterpriseId * 79
+ mReservationId * 83;
+ mReservationId * 83
+ Boolean.hashCode(mMatchNonThreadLocalNetworks) * 89;
}
@Override
@ -2418,6 +2423,7 @@ public final class NetworkCapabilities implements Parcelable {
dest.writeTypedList(mUnderlyingNetworks);
dest.writeInt(mEnterpriseId & ALL_VALID_ENTERPRISE_IDS);
dest.writeInt(mReservationId);
dest.writeBoolean(mMatchNonThreadLocalNetworks);
}
public static final @android.annotation.NonNull Creator<NetworkCapabilities> CREATOR =
@ -2454,8 +2460,10 @@ public final class NetworkCapabilities implements Parcelable {
netCap.setUnderlyingNetworks(in.createTypedArrayList(Network.CREATOR));
netCap.mEnterpriseId = in.readInt() & ALL_VALID_ENTERPRISE_IDS;
netCap.mReservationId = in.readInt();
netCap.mMatchNonThreadLocalNetworks = in.readBoolean();
return netCap;
}
@Override
public NetworkCapabilities[] newArray(int size) {
return new NetworkCapabilities[size];
@ -2561,6 +2569,10 @@ public final class NetworkCapabilities implements Parcelable {
sb.append(" ReservationId: ").append(isReservationOffer ? "*" : mReservationId);
}
if (mMatchNonThreadLocalNetworks) {
sb.append(" MatchNonThreadLocalNetworks");
}
sb.append(" UnderlyingNetworks: ");
if (mUnderlyingNetworks != null) {
sb.append("[");
@ -2945,7 +2957,45 @@ public final class NetworkCapabilities implements Parcelable {
return mReservationId == nc.mReservationId;
}
/**
* Flag to control whether a NetworkRequest can match non-thread local networks.
* @hide
*/
// TODO: Change to default disabled when introduce this filtering.
private boolean mMatchNonThreadLocalNetworks = true;
/**
* Returns the match non-thread local networks flag.
*
* @hide
*/
public boolean getMatchNonThreadLocalNetworks() {
return mMatchNonThreadLocalNetworks;
}
/**
* Set the match non-thread local networks flag.
* @hide
*/
public void setMatchNonThreadLocalNetworks(boolean enabled) {
mMatchNonThreadLocalNetworks = enabled;
}
private boolean equalsMatchNonThreadLocalNetworks(@NonNull NetworkCapabilities nc) {
return mMatchNonThreadLocalNetworks == nc.mMatchNonThreadLocalNetworks;
}
// If the flag was set, the NetworkRequest can match all local networks.
// Otherwise, it can only see local networks created by Thread.
@SuppressWarnings("FlaggedApi")
private boolean satisfiedByMatchNonThreadLocalNetworks(@NonNull NetworkCapabilities nc) {
// If the network is not a local network, out of scope.
if (!nc.hasCapability(NET_CAPABILITY_LOCAL_NETWORK)) return true;
// If there is no restriction on matching non-thread local networks, return.
if (mMatchNonThreadLocalNetworks) return true;
return nc.hasTransport(TRANSPORT_THREAD);
}
/**
* Returns a bitmask of all the applicable redactions (based on the permissions held by the

View file

@ -56,6 +56,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
import static android.net.NetworkCapabilities.TRANSPORT_SATELLITE;
import static android.net.NetworkCapabilities.TRANSPORT_TEST;
import static android.net.NetworkCapabilities.TRANSPORT_THREAD;
import static android.net.NetworkCapabilities.TRANSPORT_USB;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
@ -1532,4 +1533,93 @@ public class NetworkCapabilitiesTest {
nc.setReservationId(43);
assertNotEquals(nc, other);
}
@Test
public void testMatchNonThreadLocalNetworks_equals() {
final NetworkCapabilities nc = new NetworkCapabilities();
nc.setMatchNonThreadLocalNetworks(true);
final NetworkCapabilities other = new NetworkCapabilities(nc);
assertEquals(nc, other);
nc.setMatchNonThreadLocalNetworks(false);
assertNotEquals(nc, other);
}
@Test
public void testMatchNonThreadLocalNetworks_enabled() {
doTestMatchNonThreadLocalNetworks(true);
}
@Test
public void testMatchNonThreadLocalNetworks_disabled() {
doTestMatchNonThreadLocalNetworks(false);
}
private void doTestMatchNonThreadLocalNetworks(boolean enabled) {
// Setup request NCs.
final NetworkCapabilities noTransportRequestNc = new NetworkCapabilities();
final NetworkCapabilities threadRequestNc =
new NetworkCapabilities.Builder().addTransportType(TRANSPORT_THREAD).build();
final NetworkCapabilities wifiRequestNc =
new NetworkCapabilities.Builder().addTransportType(TRANSPORT_WIFI).build();
final NetworkCapabilities multiTransportRequestNc =
new NetworkCapabilities.Builder().addTransportType(
TRANSPORT_THREAD).addTransportType(TRANSPORT_WIFI).build();
// Setup network NCs.
final NetworkCapabilities localNoTransportNc = new NetworkCapabilities.Builder()
.addCapability(NET_CAPABILITY_LOCAL_NETWORK).build();
final NetworkCapabilities localThreadsNc = new NetworkCapabilities.Builder()
.addCapability(NET_CAPABILITY_LOCAL_NETWORK)
.addTransportType(TRANSPORT_THREAD).build();
final NetworkCapabilities localWifiNc = new NetworkCapabilities.Builder()
.addCapability(NET_CAPABILITY_LOCAL_NETWORK)
.addTransportType(TRANSPORT_WIFI).build();
final NetworkCapabilities wanWifiNc = new NetworkCapabilities.Builder()
.addTransportType(TRANSPORT_WIFI).build();
// Mark flags accordingly.
noTransportRequestNc.setMatchNonThreadLocalNetworks(enabled);
threadRequestNc.setMatchNonThreadLocalNetworks(enabled);
wifiRequestNc.setMatchNonThreadLocalNetworks(enabled);
multiTransportRequestNc.setMatchNonThreadLocalNetworks(enabled);
if (enabled) {
// A request with no specific transport matches all networks.
assertTrue(noTransportRequestNc.satisfiedByNetworkCapabilities(localNoTransportNc));
assertTrue(noTransportRequestNc.satisfiedByNetworkCapabilities(localWifiNc));
} else {
// A request with no specific transport only matches thread networks.
assertFalse(noTransportRequestNc.satisfiedByNetworkCapabilities(localNoTransportNc));
assertFalse(noTransportRequestNc.satisfiedByNetworkCapabilities(localWifiNc));
}
assertTrue(noTransportRequestNc.satisfiedByNetworkCapabilities(localThreadsNc));
assertTrue(noTransportRequestNc.satisfiedByNetworkCapabilities(wanWifiNc));
// A request with TRANSPORT_THREAD only matches thread networks.
assertFalse(threadRequestNc.satisfiedByNetworkCapabilities(localNoTransportNc));
assertTrue(threadRequestNc.satisfiedByNetworkCapabilities(localThreadsNc));
assertFalse(threadRequestNc.satisfiedByNetworkCapabilities(localWifiNc));
assertFalse(threadRequestNc.satisfiedByNetworkCapabilities(wanWifiNc));
assertFalse(multiTransportRequestNc.satisfiedByNetworkCapabilities(localNoTransportNc));
assertTrue(multiTransportRequestNc.satisfiedByNetworkCapabilities(localThreadsNc));
assertTrue(multiTransportRequestNc.satisfiedByNetworkCapabilities(wanWifiNc));
if (enabled) {
assertTrue(multiTransportRequestNc.satisfiedByNetworkCapabilities(localWifiNc));
} else {
// A request with multiple transports only matches thread networks.
assertFalse(multiTransportRequestNc.satisfiedByNetworkCapabilities(localWifiNc));
}
assertFalse(wifiRequestNc.satisfiedByNetworkCapabilities(localNoTransportNc));
assertFalse(wifiRequestNc.satisfiedByNetworkCapabilities(localThreadsNc));
assertTrue(wifiRequestNc.satisfiedByNetworkCapabilities(wanWifiNc));
if (enabled) {
assertTrue(wifiRequestNc.satisfiedByNetworkCapabilities(localWifiNc));
} else {
// A request without TRANSPORT_THREAD matches nothing.
assertFalse(wifiRequestNc.satisfiedByNetworkCapabilities(localWifiNc));
}
}
}