Merge changes Icecb889a,Id06116ad into main
* changes: Set the reservationId when a new NetworkRequest is created Add reservationId to NetworkCapabilities
This commit is contained in:
commit
3a5b37a87c
5 changed files with 158 additions and 8 deletions
|
|
@ -359,6 +359,7 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
mSubIds = new ArraySet<>();
|
||||
mUnderlyingNetworks = null;
|
||||
mEnterpriseId = 0;
|
||||
mReservationId = RES_ID_UNSET;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -393,6 +394,7 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
// necessary.
|
||||
mUnderlyingNetworks = nc.mUnderlyingNetworks;
|
||||
mEnterpriseId = nc.mEnterpriseId;
|
||||
mReservationId = nc.mReservationId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2233,7 +2235,8 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
&& (onlyImmutable || satisfiedByUids(nc))
|
||||
&& (onlyImmutable || satisfiedBySSID(nc))
|
||||
&& (onlyImmutable || satisfiedByRequestor(nc))
|
||||
&& (onlyImmutable || satisfiedBySubscriptionIds(nc)));
|
||||
&& (onlyImmutable || satisfiedBySubscriptionIds(nc)))
|
||||
&& satisfiedByReservationId(nc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2347,7 +2350,8 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
&& equalsAdministratorUids(that)
|
||||
&& equalsSubscriptionIds(that)
|
||||
&& equalsUnderlyingNetworks(that)
|
||||
&& equalsEnterpriseCapabilitiesId(that);
|
||||
&& equalsEnterpriseCapabilitiesId(that)
|
||||
&& equalsReservationId(that);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -2373,7 +2377,9 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
+ Arrays.hashCode(mAdministratorUids) * 67
|
||||
+ Objects.hashCode(mSubIds) * 71
|
||||
+ Objects.hashCode(mUnderlyingNetworks) * 73
|
||||
+ mEnterpriseId * 79;
|
||||
+ mEnterpriseId * 79
|
||||
+ mReservationId * 83;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -2411,6 +2417,7 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
dest.writeIntArray(CollectionUtils.toIntArray(mSubIds));
|
||||
dest.writeTypedList(mUnderlyingNetworks);
|
||||
dest.writeInt(mEnterpriseId & ALL_VALID_ENTERPRISE_IDS);
|
||||
dest.writeInt(mReservationId);
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Creator<NetworkCapabilities> CREATOR =
|
||||
|
|
@ -2446,6 +2453,7 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
}
|
||||
netCap.setUnderlyingNetworks(in.createTypedArrayList(Network.CREATOR));
|
||||
netCap.mEnterpriseId = in.readInt() & ALL_VALID_ENTERPRISE_IDS;
|
||||
netCap.mReservationId = in.readInt();
|
||||
return netCap;
|
||||
}
|
||||
@Override
|
||||
|
|
@ -2548,6 +2556,11 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
NetworkCapabilities::enterpriseIdNameOf, "&");
|
||||
}
|
||||
|
||||
if (mReservationId != RES_ID_UNSET) {
|
||||
final boolean isReservationOffer = (mReservationId == RES_ID_MATCH_ALL_RESERVATIONS);
|
||||
sb.append(" ReservationId: ").append(isReservationOffer ? "*" : mReservationId);
|
||||
}
|
||||
|
||||
sb.append(" UnderlyingNetworks: ");
|
||||
if (mUnderlyingNetworks != null) {
|
||||
sb.append("[");
|
||||
|
|
@ -2875,6 +2888,65 @@ public final class NetworkCapabilities implements Parcelable {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The reservation ID used by non-reservable Networks and "regular" NetworkOffers.
|
||||
*
|
||||
* Note that {@code NetworkRequest#FIRST_REQUEST_ID} is 1;
|
||||
* @hide
|
||||
*/
|
||||
public static final int RES_ID_UNSET = 0;
|
||||
|
||||
/**
|
||||
* The reservation ID used by special NetworkOffers that handle RESERVATION requests.
|
||||
*
|
||||
* NetworkOffers with {@code RES_ID_MATCH_ALL_RESERVATIONS} *only* receive onNetworkNeeded()
|
||||
* callbacks for {@code NetworkRequest.Type.RESERVATION}.
|
||||
* @hide
|
||||
*/
|
||||
public static final int RES_ID_MATCH_ALL_RESERVATIONS = -1;
|
||||
|
||||
/**
|
||||
* Unique ID that identifies the network reservation.
|
||||
*/
|
||||
private int mReservationId;
|
||||
|
||||
/**
|
||||
* Returns the reservation ID
|
||||
* @hide
|
||||
*/
|
||||
public int getReservationId() {
|
||||
return mReservationId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the reservation ID
|
||||
* @hide
|
||||
*/
|
||||
public void setReservationId(int resId) {
|
||||
mReservationId = resId;
|
||||
}
|
||||
|
||||
private boolean equalsReservationId(@NonNull NetworkCapabilities nc) {
|
||||
return mReservationId == nc.mReservationId;
|
||||
}
|
||||
|
||||
private boolean satisfiedByReservationId(@NonNull NetworkCapabilities nc) {
|
||||
if (mReservationId == RES_ID_UNSET) {
|
||||
// To maintain regular NetworkRequest semantics, a request with a zero reservationId
|
||||
// matches an offer or network with any reservationId except MATCH_ALL_RESERVATIONS.
|
||||
return nc.mReservationId != RES_ID_MATCH_ALL_RESERVATIONS;
|
||||
}
|
||||
// A request with a non-zero reservationId matches only an offer or network with that exact
|
||||
// reservationId (required to match the network that will eventually come up) or
|
||||
// MATCH_ALL_RESERVATIONS (required to match the blanket reservation offer).
|
||||
if (nc.mReservationId == RES_ID_MATCH_ALL_RESERVATIONS) {
|
||||
return true;
|
||||
}
|
||||
return mReservationId == nc.mReservationId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns a bitmask of all the applicable redactions (based on the permissions held by the
|
||||
* receiving app) to be performed on this object.
|
||||
|
|
|
|||
|
|
@ -258,6 +258,12 @@ public class NetworkRequest implements Parcelable {
|
|||
}
|
||||
requestId = rId;
|
||||
networkCapabilities = nc;
|
||||
if (type == Type.RESERVATION) {
|
||||
// Conceptually, the reservationId is not related to the requestId; however, the
|
||||
// requestId fulfills the same uniqueness requirements that are needed for the
|
||||
// reservationId, so it can be reused for this purpose.
|
||||
networkCapabilities.setReservationId(rId);
|
||||
}
|
||||
this.legacyType = legacyType;
|
||||
this.type = type;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -382,6 +382,7 @@ public class NetworkCapabilitiesTest {
|
|||
netCap.setAllowedUids(allowedUids);
|
||||
netCap.setSubscriptionIds(Set.of(TEST_SUBID1, TEST_SUBID2));
|
||||
netCap.setUids(uids);
|
||||
netCap.setReservationId(42);
|
||||
}
|
||||
|
||||
netCap.setOwnerUid(123);
|
||||
|
|
@ -1493,4 +1494,42 @@ public class NetworkCapabilitiesTest {
|
|||
// nc1 and nc2 are the same since invalid capability is ignored
|
||||
assertEquals(nc1, nc2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReservationIdMatching() {
|
||||
final NetworkCapabilities requestNc = new NetworkCapabilities();
|
||||
final NetworkCapabilities reservationNc = new NetworkCapabilities();
|
||||
reservationNc.setReservationId(42);
|
||||
|
||||
final NetworkCapabilities reservedNetworkNc = new NetworkCapabilities(reservationNc);
|
||||
final NetworkCapabilities otherNetworkNc = new NetworkCapabilities();
|
||||
final NetworkCapabilities otherReservedNetworkNc = new NetworkCapabilities();
|
||||
otherReservedNetworkNc.setReservationId(99);
|
||||
final NetworkCapabilities offerNc = new NetworkCapabilities();
|
||||
offerNc.setReservationId(NetworkCapabilities.RES_ID_MATCH_ALL_RESERVATIONS);
|
||||
|
||||
// A regular request can match any network or offer except one with MATCH_ALL_RESERVATIONS
|
||||
assertTrue(requestNc.satisfiedByNetworkCapabilities(reservedNetworkNc));
|
||||
assertTrue(requestNc.satisfiedByNetworkCapabilities(otherNetworkNc));
|
||||
assertTrue(requestNc.satisfiedByNetworkCapabilities(otherReservedNetworkNc));
|
||||
assertFalse(requestNc.satisfiedByNetworkCapabilities(offerNc));
|
||||
|
||||
// A reservation request can only match the reservedNetwork and the blanket offer.
|
||||
assertTrue(reservationNc.satisfiedByNetworkCapabilities(reservedNetworkNc));
|
||||
assertFalse(reservationNc.satisfiedByNetworkCapabilities(otherNetworkNc));
|
||||
assertFalse(reservationNc.satisfiedByNetworkCapabilities(otherReservedNetworkNc));
|
||||
assertTrue(reservationNc.satisfiedByNetworkCapabilities(offerNc));
|
||||
}
|
||||
|
||||
@Test @IgnoreUpTo(SC_V2)
|
||||
public void testReservationIdEquals() {
|
||||
final NetworkCapabilities nc = new NetworkCapabilities();
|
||||
nc.setReservationId(42);
|
||||
final NetworkCapabilities other = new NetworkCapabilities(nc);
|
||||
|
||||
assertEquals(nc, other);
|
||||
|
||||
nc.setReservationId(43);
|
||||
assertNotEquals(nc, other);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package android.net.cts;
|
||||
|
||||
import static android.net.ConnectivityManager.TYPE_NONE;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
|
||||
|
|
@ -554,4 +555,32 @@ public class NetworkRequestTest {
|
|||
.setBssidPattern(ARBITRARY_ADDRESS, ARBITRARY_ADDRESS)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
@IgnoreUpTo(Build.VERSION_CODES.R)
|
||||
public void testNetworkReservation() {
|
||||
final NetworkCapabilities nc = new NetworkCapabilities();
|
||||
final NetworkCapabilities blanketOffer = new NetworkCapabilities(nc);
|
||||
blanketOffer.setReservationId(NetworkCapabilities.RES_ID_MATCH_ALL_RESERVATIONS);
|
||||
final NetworkCapabilities specificOffer = new NetworkCapabilities(nc);
|
||||
specificOffer.setReservationId(42);
|
||||
final NetworkCapabilities otherSpecificOffer = new NetworkCapabilities(nc);
|
||||
otherSpecificOffer.setReservationId(43);
|
||||
final NetworkCapabilities regularOffer = new NetworkCapabilities(nc);
|
||||
|
||||
final NetworkRequest reservationNR = new NetworkRequest(new NetworkCapabilities(nc),
|
||||
TYPE_NONE, 42 /* rId */, NetworkRequest.Type.RESERVATION);
|
||||
final NetworkRequest requestNR = new NetworkRequest(new NetworkCapabilities(nc),
|
||||
TYPE_NONE, 42 /* rId */, NetworkRequest.Type.REQUEST);
|
||||
|
||||
assertTrue(reservationNR.canBeSatisfiedBy(blanketOffer));
|
||||
assertTrue(reservationNR.canBeSatisfiedBy(specificOffer));
|
||||
assertFalse(reservationNR.canBeSatisfiedBy(otherSpecificOffer));
|
||||
assertFalse(reservationNR.canBeSatisfiedBy(regularOffer));
|
||||
|
||||
assertFalse(requestNR.canBeSatisfiedBy(blanketOffer));
|
||||
assertTrue(requestNR.canBeSatisfiedBy(specificOffer));
|
||||
assertTrue(requestNR.canBeSatisfiedBy(otherSpecificOffer));
|
||||
assertTrue(requestNR.canBeSatisfiedBy(regularOffer));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import android.net.NetworkCapabilities
|
|||
import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED
|
||||
import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED
|
||||
import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
|
||||
import android.net.NetworkCapabilities.RES_ID_MATCH_ALL_RESERVATIONS
|
||||
import android.net.NetworkCapabilities.TRANSPORT_ETHERNET
|
||||
import android.net.NetworkProvider
|
||||
import android.net.NetworkRequest
|
||||
|
|
@ -60,22 +61,25 @@ class CSNetworkReservationTest : CSTest() {
|
|||
context.packageName, context.attributionTag, NetworkCallback.DECLARED_METHODS_ALL)
|
||||
}
|
||||
|
||||
fun NetworkCapabilities.copyWithReservationId(resId: Int) = NetworkCapabilities(this).also {
|
||||
it.reservationId = resId
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testReservationTriggersOnNetworkNeeded() {
|
||||
val provider = NetworkProvider(context, csHandlerThread.looper, "Ethernet provider")
|
||||
val offerCb = TestableNetworkOfferCallback(TIMEOUT_MS, NO_CB_TIMEOUT_MS)
|
||||
val blanketOfferCb = TestableNetworkOfferCallback(TIMEOUT_MS, NO_CB_TIMEOUT_MS)
|
||||
|
||||
cm.registerNetworkProvider(provider)
|
||||
provider.registerNetworkOffer(ETHERNET_SCORE, ETHERNET_CAPS, {r -> r.run()}, offerCb)
|
||||
|
||||
// TODO: add reservationId to offer, so it doesn't match the default request.
|
||||
offerCb.expectOnNetworkNeeded(ETHERNET_CAPS)
|
||||
val blanketCaps = ETHERNET_CAPS.copyWithReservationId(RES_ID_MATCH_ALL_RESERVATIONS)
|
||||
provider.registerNetworkOffer(ETHERNET_SCORE, blanketCaps, {r -> r.run()}, blanketOfferCb)
|
||||
|
||||
val req = NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET).build()
|
||||
val cb = NetworkCallback()
|
||||
cm.reserveNetwork(req, cb)
|
||||
|
||||
offerCb.expectOnNetworkNeeded(req.networkCapabilities)
|
||||
blanketOfferCb.expectOnNetworkNeeded(blanketCaps)
|
||||
|
||||
// TODO: also test onNetworkUnneeded is called once ConnectivityManager supports the
|
||||
// reserveNetwork API.
|
||||
|
|
|
|||
Loading…
Reference in a new issue