Merge "Add new APIs in NetworkCapabilities to set and get underlying networks"
This commit is contained in:
@@ -279,6 +279,7 @@ package android.net {
|
||||
method @Nullable public String getSsid();
|
||||
method @NonNull public java.util.Set<java.lang.Integer> getSubscriptionIds();
|
||||
method @NonNull public int[] getTransportTypes();
|
||||
method @Nullable public java.util.List<android.net.Network> getUnderlyingNetworks();
|
||||
method public boolean isPrivateDnsBroken();
|
||||
method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities);
|
||||
field public static final int NET_CAPABILITY_BIP = 31; // 0x1f
|
||||
@@ -309,6 +310,7 @@ package android.net {
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setSsid(@Nullable String);
|
||||
method @NonNull public android.net.NetworkCapabilities.Builder setSubscriptionIds(@NonNull java.util.Set<java.lang.Integer>);
|
||||
method @NonNull public android.net.NetworkCapabilities.Builder setTransportInfo(@Nullable android.net.TransportInfo);
|
||||
method @NonNull public android.net.NetworkCapabilities.Builder setUnderlyingNetworks(@Nullable java.util.List<android.net.Network>);
|
||||
method @NonNull public static android.net.NetworkCapabilities.Builder withoutDefaultCapabilities();
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,10 @@ import com.android.net.module.util.NetworkCapabilitiesUtils;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.StringJoiner;
|
||||
@@ -129,6 +132,11 @@ public final class NetworkCapabilities implements Parcelable {
|
||||
// Set to true when private DNS is broken.
|
||||
private boolean mPrivateDnsBroken;
|
||||
|
||||
// Underlying networks, if any. VPNs and VCNs typically have underlying networks.
|
||||
// This is an unmodifiable list and it will be returned as is in the getter.
|
||||
@Nullable
|
||||
private List<Network> mUnderlyingNetworks;
|
||||
|
||||
/**
|
||||
* Uid of the app making the request.
|
||||
*/
|
||||
@@ -184,6 +192,7 @@ public final class NetworkCapabilities implements Parcelable {
|
||||
mRequestorUid = Process.INVALID_UID;
|
||||
mRequestorPackageName = null;
|
||||
mSubIds = new ArraySet<>();
|
||||
mUnderlyingNetworks = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -213,6 +222,9 @@ public final class NetworkCapabilities implements Parcelable {
|
||||
mRequestorUid = nc.mRequestorUid;
|
||||
mRequestorPackageName = nc.mRequestorPackageName;
|
||||
mSubIds = new ArraySet<>(nc.mSubIds);
|
||||
// mUnderlyingNetworks is an unmodifiable list if non-null, so a defensive copy is not
|
||||
// necessary.
|
||||
mUnderlyingNetworks = nc.mUnderlyingNetworks;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -698,6 +710,41 @@ public final class NetworkCapabilities implements Parcelable {
|
||||
setCapabilities(capabilities, new int[] {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the underlying networks of this network.
|
||||
*
|
||||
* @param networks The underlying networks of this network.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void setUnderlyingNetworks(@Nullable List<Network> networks) {
|
||||
mUnderlyingNetworks =
|
||||
(networks == null) ? null : Collections.unmodifiableList(new ArrayList<>(networks));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the underlying networks of this network. If the caller is not system privileged, this is
|
||||
* always redacted to null and it will be never useful to the caller.
|
||||
*
|
||||
* @return <li>If the list is null, this network hasn't declared underlying networks.</li>
|
||||
* <li>If the list is empty, this network has declared that it has no underlying
|
||||
* networks or it doesn't run on any of the available networks.</li>
|
||||
* <li>The list can contain multiple underlying networks, e.g. a VPN running over
|
||||
* multiple networks at the same time.</li>
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SuppressLint("NullableCollection")
|
||||
@Nullable
|
||||
@SystemApi
|
||||
public List<Network> getUnderlyingNetworks() {
|
||||
return mUnderlyingNetworks;
|
||||
}
|
||||
|
||||
private boolean equalsUnderlyingNetworks(@NonNull NetworkCapabilities nc) {
|
||||
return Objects.equals(getUnderlyingNetworks(), nc.getUnderlyingNetworks());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for the presence of a capability on this instance.
|
||||
*
|
||||
@@ -1901,7 +1948,8 @@ public final class NetworkCapabilities implements Parcelable {
|
||||
&& equalsPrivateDnsBroken(that)
|
||||
&& equalsRequestor(that)
|
||||
&& equalsAdministratorUids(that)
|
||||
&& equalsSubscriptionIds(that);
|
||||
&& equalsSubscriptionIds(that)
|
||||
&& equalsUnderlyingNetworks(that);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1924,7 +1972,8 @@ public final class NetworkCapabilities implements Parcelable {
|
||||
+ Objects.hashCode(mRequestorUid) * 53
|
||||
+ Objects.hashCode(mRequestorPackageName) * 59
|
||||
+ Arrays.hashCode(mAdministratorUids) * 61
|
||||
+ Objects.hashCode(mSubIds) * 67;
|
||||
+ Objects.hashCode(mSubIds) * 67
|
||||
+ Objects.hashCode(mUnderlyingNetworks) * 71;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1959,6 +2008,7 @@ public final class NetworkCapabilities implements Parcelable {
|
||||
dest.writeInt(mRequestorUid);
|
||||
dest.writeString(mRequestorPackageName);
|
||||
dest.writeIntArray(CollectionUtils.toIntArray(mSubIds));
|
||||
dest.writeTypedList(mUnderlyingNetworks);
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Creator<NetworkCapabilities> CREATOR =
|
||||
@@ -1987,6 +2037,7 @@ public final class NetworkCapabilities implements Parcelable {
|
||||
for (int i = 0; i < subIdInts.length; i++) {
|
||||
netCap.mSubIds.add(subIdInts[i]);
|
||||
}
|
||||
netCap.setUnderlyingNetworks(in.createTypedArrayList(Network.CREATOR));
|
||||
return netCap;
|
||||
}
|
||||
@Override
|
||||
@@ -2078,6 +2129,16 @@ public final class NetworkCapabilities implements Parcelable {
|
||||
sb.append(" SubscriptionIds: ").append(mSubIds);
|
||||
}
|
||||
|
||||
if (mUnderlyingNetworks != null && mUnderlyingNetworks.size() > 0) {
|
||||
sb.append(" Underlying networks: [");
|
||||
final StringJoiner joiner = new StringJoiner(",");
|
||||
for (int i = 0; i < mUnderlyingNetworks.size(); i++) {
|
||||
joiner.add(mUnderlyingNetworks.get(i).toString());
|
||||
}
|
||||
sb.append(joiner.toString());
|
||||
sb.append("]");
|
||||
}
|
||||
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
@@ -2795,6 +2856,17 @@ public final class NetworkCapabilities implements Parcelable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the underlying networks of this network.
|
||||
*
|
||||
* @param networks The underlying networks of this network.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setUnderlyingNetworks(@Nullable List<Network> networks) {
|
||||
mCaps.setUnderlyingNetworks(networks);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the instance of the capabilities.
|
||||
*
|
||||
|
||||
@@ -50,6 +50,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.isAtLeastS;
|
||||
import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
|
||||
import static com.android.testutils.MiscAsserts.assertEmpty;
|
||||
import static com.android.testutils.MiscAsserts.assertThrows;
|
||||
import static com.android.testutils.ParcelUtils.assertParcelSane;
|
||||
@@ -84,7 +85,9 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@@ -342,7 +345,9 @@ public class NetworkCapabilitiesTest {
|
||||
}
|
||||
|
||||
private void testParcelSane(NetworkCapabilities cap) {
|
||||
if (isAtLeastS()) {
|
||||
if (isAtLeastT()) {
|
||||
assertParcelSane(cap, 17);
|
||||
} else if (isAtLeastS()) {
|
||||
assertParcelSane(cap, 16);
|
||||
} else if (isAtLeastR()) {
|
||||
assertParcelSane(cap, 15);
|
||||
@@ -711,6 +716,47 @@ public class NetworkCapabilitiesTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnderlyingNetworks() {
|
||||
assumeTrue(isAtLeastT());
|
||||
final NetworkCapabilities nc = new NetworkCapabilities();
|
||||
final Network network1 = new Network(100);
|
||||
final Network network2 = new Network(101);
|
||||
final ArrayList<Network> inputNetworks = new ArrayList<>();
|
||||
inputNetworks.add(network1);
|
||||
inputNetworks.add(network2);
|
||||
nc.setUnderlyingNetworks(inputNetworks);
|
||||
final ArrayList<Network> outputNetworks = new ArrayList<>(nc.getUnderlyingNetworks());
|
||||
assertEquals(network1, outputNetworks.get(0));
|
||||
assertEquals(network2, outputNetworks.get(1));
|
||||
nc.setUnderlyingNetworks(null);
|
||||
assertNull(nc.getUnderlyingNetworks());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqualsForUnderlyingNetworks() {
|
||||
assumeTrue(isAtLeastT());
|
||||
final NetworkCapabilities nc1 = new NetworkCapabilities();
|
||||
final NetworkCapabilities nc2 = new NetworkCapabilities();
|
||||
assertEquals(nc1, nc2);
|
||||
final Network network = new Network(100);
|
||||
final ArrayList<Network> inputNetworks = new ArrayList<>();
|
||||
final ArrayList<Network> emptyList = new ArrayList<>();
|
||||
inputNetworks.add(network);
|
||||
nc1.setUnderlyingNetworks(inputNetworks);
|
||||
assertNotEquals(nc1, nc2);
|
||||
nc2.setUnderlyingNetworks(inputNetworks);
|
||||
assertEquals(nc1, nc2);
|
||||
nc1.setUnderlyingNetworks(emptyList);
|
||||
assertNotEquals(nc1, nc2);
|
||||
nc2.setUnderlyingNetworks(emptyList);
|
||||
assertEquals(nc1, nc2);
|
||||
nc1.setUnderlyingNetworks(null);
|
||||
assertNotEquals(nc1, nc2);
|
||||
nc2.setUnderlyingNetworks(null);
|
||||
assertEquals(nc1, nc2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetNetworkSpecifierOnMultiTransportNc() {
|
||||
// Sequence 1: Transport + Transport + NetworkSpecifier
|
||||
@@ -1109,7 +1155,7 @@ public class NetworkCapabilitiesTest {
|
||||
final TransportInfo transportInfo = new TransportInfo() {};
|
||||
final String ssid = "TEST_SSID";
|
||||
final String packageName = "com.google.test.networkcapabilities";
|
||||
final NetworkCapabilities nc = new NetworkCapabilities.Builder()
|
||||
final NetworkCapabilities.Builder capBuilder = new NetworkCapabilities.Builder()
|
||||
.addTransportType(TRANSPORT_WIFI)
|
||||
.addTransportType(TRANSPORT_CELLULAR)
|
||||
.removeTransportType(TRANSPORT_CELLULAR)
|
||||
@@ -1125,8 +1171,14 @@ public class NetworkCapabilitiesTest {
|
||||
.setSignalStrength(signalStrength)
|
||||
.setSsid(ssid)
|
||||
.setRequestorUid(requestUid)
|
||||
.setRequestorPackageName(packageName)
|
||||
.build();
|
||||
.setRequestorPackageName(packageName);
|
||||
final Network network1 = new Network(100);
|
||||
final Network network2 = new Network(101);
|
||||
final List<Network> inputNetworks = List.of(network1, network2);
|
||||
if (isAtLeastT()) {
|
||||
capBuilder.setUnderlyingNetworks(inputNetworks);
|
||||
}
|
||||
final NetworkCapabilities nc = capBuilder.build();
|
||||
assertEquals(1, nc.getTransportTypes().length);
|
||||
assertEquals(TRANSPORT_WIFI, nc.getTransportTypes()[0]);
|
||||
assertTrue(nc.hasCapability(NET_CAPABILITY_EIMS));
|
||||
@@ -1144,6 +1196,11 @@ public class NetworkCapabilitiesTest {
|
||||
assertEquals(ssid, nc.getSsid());
|
||||
assertEquals(requestUid, nc.getRequestorUid());
|
||||
assertEquals(packageName, nc.getRequestorPackageName());
|
||||
if (isAtLeastT()) {
|
||||
final List<Network> outputNetworks = nc.getUnderlyingNetworks();
|
||||
assertEquals(network1, outputNetworks.get(0));
|
||||
assertEquals(network2, outputNetworks.get(1));
|
||||
}
|
||||
// Cannot assign null into NetworkCapabilities.Builder
|
||||
try {
|
||||
final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder(null);
|
||||
|
||||
Reference in New Issue
Block a user