Merge changes from topics "vcn04", "vcn12"

* changes:
  [VCN12] Expose setSubIds/getSubIds APIs
  [VCN04] Add Subscription Id set into NetworkCapabilities
This commit is contained in:
Junyu Lai
2021-03-12 07:12:59 +00:00
committed by Gerrit Code Review
5 changed files with 205 additions and 16 deletions

View File

@@ -295,6 +295,7 @@ package android.net {
method @Nullable public android.net.NetworkSpecifier getNetworkSpecifier();
method public int getOwnerUid();
method public int getSignalStrength();
method @NonNull public java.util.Set<java.lang.Integer> getSubIds();
method @Nullable public android.net.TransportInfo getTransportInfo();
method public boolean hasCapability(int);
method public boolean hasTransport(int);
@@ -401,6 +402,7 @@ package android.net {
method public android.net.NetworkRequest.Builder removeTransportType(int);
method @Deprecated public android.net.NetworkRequest.Builder setNetworkSpecifier(String);
method public android.net.NetworkRequest.Builder setNetworkSpecifier(android.net.NetworkSpecifier);
method @NonNull public android.net.NetworkRequest.Builder setSubIds(@NonNull java.util.Set<java.lang.Integer>);
}
public class ParseException extends java.lang.RuntimeException {

View File

@@ -296,6 +296,7 @@ package android.net {
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setRequestorUid(int);
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkCapabilities.Builder setSignalStrength(int);
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setSsid(@Nullable String);
method @NonNull public android.net.NetworkCapabilities.Builder setSubIds(@NonNull java.util.Set<java.lang.Integer>);
method @NonNull public android.net.NetworkCapabilities.Builder setTransportInfo(@Nullable android.net.TransportInfo);
}

View File

@@ -132,6 +132,7 @@ public final class NetworkCapabilities implements Parcelable {
mPrivateDnsBroken = false;
mRequestorUid = Process.INVALID_UID;
mRequestorPackageName = null;
mSubIds = new ArraySet<>();
}
/**
@@ -160,6 +161,7 @@ public final class NetworkCapabilities implements Parcelable {
mPrivateDnsBroken = nc.mPrivateDnsBroken;
mRequestorUid = nc.mRequestorUid;
mRequestorPackageName = nc.mRequestorPackageName;
mSubIds = new ArraySet<>(nc.mSubIds);
}
/**
@@ -1666,6 +1668,7 @@ public final class NetworkCapabilities implements Parcelable {
combineSSIDs(nc);
combineRequestor(nc);
combineAdministratorUids(nc);
combineSubIds(nc);
}
/**
@@ -1685,8 +1688,9 @@ public final class NetworkCapabilities implements Parcelable {
&& satisfiedBySpecifier(nc)
&& (onlyImmutable || satisfiedBySignalStrength(nc))
&& (onlyImmutable || satisfiedByUids(nc))
&& (onlyImmutable || satisfiedBySSID(nc)))
&& (onlyImmutable || satisfiedByRequestor(nc));
&& (onlyImmutable || satisfiedBySSID(nc))
&& (onlyImmutable || satisfiedByRequestor(nc))
&& (onlyImmutable || satisfiedBySubIds(nc)));
}
/**
@@ -1782,7 +1786,8 @@ public final class NetworkCapabilities implements Parcelable {
&& equalsOwnerUid(that)
&& equalsPrivateDnsBroken(that)
&& equalsRequestor(that)
&& equalsAdministratorUids(that);
&& equalsAdministratorUids(that)
&& equalsSubIds(that);
}
@Override
@@ -1804,7 +1809,8 @@ public final class NetworkCapabilities implements Parcelable {
+ Objects.hashCode(mPrivateDnsBroken) * 47
+ Objects.hashCode(mRequestorUid) * 53
+ Objects.hashCode(mRequestorPackageName) * 59
+ Arrays.hashCode(mAdministratorUids) * 61;
+ Arrays.hashCode(mAdministratorUids) * 61
+ Objects.hashCode(mSubIds) * 67;
}
@Override
@@ -1838,6 +1844,7 @@ public final class NetworkCapabilities implements Parcelable {
dest.writeInt(mOwnerUid);
dest.writeInt(mRequestorUid);
dest.writeString(mRequestorPackageName);
dest.writeIntArray(CollectionUtils.toIntArray(mSubIds));
}
public static final @android.annotation.NonNull Creator<NetworkCapabilities> CREATOR =
@@ -1861,6 +1868,11 @@ public final class NetworkCapabilities implements Parcelable {
netCap.mOwnerUid = in.readInt();
netCap.mRequestorUid = in.readInt();
netCap.mRequestorPackageName = in.readString();
netCap.mSubIds = new ArraySet<>();
final int[] subIdInts = Objects.requireNonNull(in.createIntArray());
for (int i = 0; i < subIdInts.length; i++) {
netCap.mSubIds.add(subIdInts[i]);
}
return netCap;
}
@Override
@@ -1944,11 +1956,14 @@ public final class NetworkCapabilities implements Parcelable {
sb.append(" SSID: ").append(mSSID);
}
if (mPrivateDnsBroken) {
sb.append(" PrivateDnsBroken");
}
if (!mSubIds.isEmpty()) {
sb.append(" SubscriptionIds: ").append(mSubIds);
}
sb.append("]");
return sb.toString();
}
@@ -2261,6 +2276,67 @@ public final class NetworkCapabilities implements Parcelable {
&& TextUtils.equals(mRequestorPackageName, nc.mRequestorPackageName);
}
/**
* Set of the subscription IDs that identifies the network or request, empty if none.
*/
@NonNull
private ArraySet<Integer> mSubIds = new ArraySet<>();
/**
* Sets the subscription ID set that associated to this network or request.
*
* @hide
*/
@NonNull
public NetworkCapabilities setSubIds(@NonNull Set<Integer> subIds) {
mSubIds = new ArraySet(Objects.requireNonNull(subIds));
return this;
}
/**
* Gets the subscription ID set that associated to this network or request.
* @return
*/
@NonNull
public Set<Integer> getSubIds() {
return new ArraySet<>(mSubIds);
}
/**
* Tests if the subscription ID set of this network is the same as that of the passed one.
*/
private boolean equalsSubIds(@NonNull NetworkCapabilities nc) {
return Objects.equals(mSubIds, nc.mSubIds);
}
/**
* Check if the subscription ID set requirements of this object are matched by the passed one.
* If specified in the request, the passed one need to have at least one subId and at least
* one of them needs to be in the request set.
*/
private boolean satisfiedBySubIds(@NonNull NetworkCapabilities nc) {
if (mSubIds.isEmpty()) return true;
if (nc.mSubIds.isEmpty()) return false;
for (final Integer subId : nc.mSubIds) {
if (mSubIds.contains(subId)) return true;
}
return false;
}
/**
* Combine subscription ID set of the capabilities.
*
* <p>This is only legal if the subscription Ids are equal.
*
* <p>If both subscription IDs are not equal, they belong to different subscription
* (or no subscription). In this case, it would not make sense to add them together.
*/
private void combineSubIds(@NonNull NetworkCapabilities nc) {
if (!Objects.equals(mSubIds, nc.mSubIds)) {
throw new IllegalStateException("Can't combine two subscription ID sets");
}
}
/**
* Builder class for NetworkCapabilities.
*
@@ -2566,6 +2642,18 @@ public final class NetworkCapabilities implements Parcelable {
return this;
}
/**
* Set the subscription ID set.
*
* @param subIds a set that represent the subscription IDs. Empty if clean up.
* @return this builder.
*/
@NonNull
public Builder setSubIds(@NonNull final Set<Integer> subIds) {
mCaps.setSubIds(subIds);
return this;
}
/**
* Builds the instance of the capabilities.
*

View File

@@ -461,6 +461,21 @@ public class NetworkRequest implements Parcelable {
}
nc.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
}
/**
* Sets the optional subscription ID set.
* <p>
* This specify the subscription IDs requirement.
* A network will satisfy this request only if it matches one of the subIds in this set.
* An empty set matches all networks, including those without a subId.
*
* @param subIds A {@code Set} that represents subscription IDs.
*/
@NonNull
public Builder setSubIds(@NonNull Set<Integer> subIds) {
mNetworkCapabilities.setSubIds(subIds);
return this;
}
}
// implement the Parcelable interface

View File

@@ -28,6 +28,7 @@ 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_RESTRICTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID;
import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE;
@@ -44,6 +45,10 @@ import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
import static android.net.NetworkCapabilities.UNRESTRICTED_CAPABILITIES;
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.testutils.MiscAsserts.assertEmpty;
import static com.android.testutils.MiscAsserts.assertThrows;
import static com.android.testutils.ParcelUtils.assertParcelSane;
import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
import static com.android.testutils.ParcelUtils.parcelingRoundTrip;
@@ -67,7 +72,6 @@ import android.util.ArraySet;
import androidx.test.runner.AndroidJUnit4;
import com.android.modules.utils.build.SdkLevel;
import com.android.testutils.CompatUtil;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
@@ -85,6 +89,9 @@ import java.util.Set;
public class NetworkCapabilitiesTest {
private static final String TEST_SSID = "TEST_SSID";
private static final String DIFFERENT_TEST_SSID = "DIFFERENT_TEST_SSID";
private static final int TEST_SUBID1 = 1;
private static final int TEST_SUBID2 = 2;
private static final int TEST_SUBID3 = 3;
@Rule
public DevSdkIgnoreRule mDevSdkIgnoreRule = new DevSdkIgnoreRule();
@@ -92,14 +99,6 @@ public class NetworkCapabilitiesTest {
private DiscoverySession mDiscoverySession = Mockito.mock(DiscoverySession.class);
private PeerHandle mPeerHandle = Mockito.mock(PeerHandle.class);
private boolean isAtLeastR() {
return SdkLevel.isAtLeastR();
}
private boolean isAtLeastS() {
return SdkLevel.isAtLeastS();
}
@Test
public void testMaybeMarkCapabilitiesRestricted() {
// verify EIMS is restricted
@@ -305,7 +304,9 @@ public class NetworkCapabilitiesTest {
.setUids(uids)
.addCapability(NET_CAPABILITY_EIMS)
.addCapability(NET_CAPABILITY_NOT_METERED);
if (isAtLeastR()) {
if (isAtLeastS()) {
netCap.setSubIds(Set.of(TEST_SUBID1, TEST_SUBID2));
} else if (isAtLeastR()) {
netCap.setOwnerUid(123);
netCap.setAdministratorUids(new int[] {5, 11});
}
@@ -380,7 +381,7 @@ public class NetworkCapabilitiesTest {
private void testParcelSane(NetworkCapabilities cap) {
if (isAtLeastS()) {
assertParcelSane(cap, 16);
assertParcelSane(cap, 17);
} else if (isAtLeastR()) {
assertParcelSane(cap, 15);
} else {
@@ -614,6 +615,20 @@ public class NetworkCapabilitiesTest {
assertFalse(nc2.appliesToUid(12));
assertTrue(nc1.appliesToUid(22));
assertTrue(nc2.appliesToUid(22));
// Verify the subscription id list can be combined only when they are equal.
if (isAtLeastS()) {
nc1.setSubIds(Set.of(TEST_SUBID1, TEST_SUBID2));
nc2.setSubIds(Set.of(TEST_SUBID2));
assertThrows(IllegalStateException.class, () -> nc2.combineCapabilities(nc1));
nc2.setSubIds(Set.of());
assertThrows(IllegalStateException.class, () -> nc2.combineCapabilities(nc1));
nc2.setSubIds(Set.of(TEST_SUBID2, TEST_SUBID1));
nc2.combineCapabilities(nc1);
assertEquals(Set.of(TEST_SUBID2, TEST_SUBID1), nc2.getSubIds());
}
}
@Test @IgnoreUpTo(Build.VERSION_CODES.Q)
@@ -762,6 +777,24 @@ public class NetworkCapabilitiesTest {
nc1.setUids(uidRange(10, 13));
nc2.set(nc1); // Overwrites, as opposed to combineCapabilities
assertEquals(nc1, nc2);
if (isAtLeastS()) {
assertThrows(NullPointerException.class, () -> nc1.setSubIds(null));
nc1.setSubIds(Set.of());
nc2.set(nc1);
assertEquals(nc1, nc2);
nc1.setSubIds(Set.of(TEST_SUBID1));
nc2.set(nc1);
assertEquals(nc1, nc2);
nc2.setSubIds(Set.of(TEST_SUBID2, TEST_SUBID1));
nc2.set(nc1);
assertEquals(nc1, nc2);
nc2.setSubIds(Set.of(TEST_SUBID3, TEST_SUBID2));
assertNotEquals(nc1, nc2);
}
}
@Test
@@ -842,6 +875,50 @@ public class NetworkCapabilitiesTest {
} catch (NullPointerException expected) { }
}
private static NetworkCapabilities capsWithSubIds(Integer ... subIds) {
// Since the NetworkRequest would put NOT_VCN_MANAGED capabilities in general, for
// every NetworkCapabilities that simulates networks needs to add it too in order to
// satisfy these requests.
final NetworkCapabilities nc = new NetworkCapabilities.Builder()
.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
.setSubIds(new ArraySet<>(subIds)).build();
assertEquals(new ArraySet<>(subIds), nc.getSubIds());
return nc;
}
@Test @IgnoreUpTo(Build.VERSION_CODES.R)
public void testSubIds() throws Exception {
final NetworkCapabilities ncWithoutId = capsWithSubIds();
final NetworkCapabilities ncWithId = capsWithSubIds(TEST_SUBID1);
final NetworkCapabilities ncWithOtherIds = capsWithSubIds(TEST_SUBID1, TEST_SUBID3);
final NetworkCapabilities ncWithoutRequestedIds = capsWithSubIds(TEST_SUBID3);
final NetworkRequest requestWithoutId = new NetworkRequest.Builder().build();
assertEmpty(requestWithoutId.networkCapabilities.getSubIds());
final NetworkRequest requestWithIds = new NetworkRequest.Builder()
.setSubIds(Set.of(TEST_SUBID1, TEST_SUBID2)).build();
assertEquals(Set.of(TEST_SUBID1, TEST_SUBID2),
requestWithIds.networkCapabilities.getSubIds());
assertFalse(requestWithIds.canBeSatisfiedBy(ncWithoutId));
assertTrue(requestWithIds.canBeSatisfiedBy(ncWithOtherIds));
assertFalse(requestWithIds.canBeSatisfiedBy(ncWithoutRequestedIds));
assertTrue(requestWithIds.canBeSatisfiedBy(ncWithId));
assertTrue(requestWithoutId.canBeSatisfiedBy(ncWithoutId));
assertTrue(requestWithoutId.canBeSatisfiedBy(ncWithId));
}
@Test @IgnoreUpTo(Build.VERSION_CODES.R)
public void testEqualsSubIds() throws Exception {
assertEquals(capsWithSubIds(), capsWithSubIds());
assertNotEquals(capsWithSubIds(), capsWithSubIds(TEST_SUBID1));
assertEquals(capsWithSubIds(TEST_SUBID1), capsWithSubIds(TEST_SUBID1));
assertNotEquals(capsWithSubIds(TEST_SUBID1), capsWithSubIds(TEST_SUBID2));
assertNotEquals(capsWithSubIds(TEST_SUBID1), capsWithSubIds(TEST_SUBID2, TEST_SUBID1));
assertEquals(capsWithSubIds(TEST_SUBID1, TEST_SUBID2),
capsWithSubIds(TEST_SUBID2, TEST_SUBID1));
}
@Test
public void testLinkBandwidthKbps() {
final NetworkCapabilities nc = new NetworkCapabilities();
@@ -1022,5 +1099,11 @@ public class NetworkCapabilitiesTest {
fail("Should not set null into NetworkCapabilities.Builder");
} catch (NullPointerException expected) { }
assertEquals(nc, new NetworkCapabilities.Builder(nc).build());
if (isAtLeastS()) {
final NetworkCapabilities nc2 = new NetworkCapabilities.Builder()
.setSubIds(Set.of(TEST_SUBID1)).build();
assertEquals(Set.of(TEST_SUBID1), nc2.getSubIds());
}
}
}