Support matches transport types in NetworkTemplate
Flag: EXEMPT implemented in the counter-part CL
Test: atest CtsNetTestCases --test-filter \
'NetworkStats*' --update-device
Test: atest ConnectivityCoverageTests --test-filter \
'NetworkStats*' --update-device
Test: atest ConnectivityCoverageTests --test-filter \
'NetworkTemplate*' --update-device
Bug: 419123367
Change-Id: I0c8bf2e24502befd810081f519ff915491b0a905
This commit is contained in:
parent
3e75b9025d
commit
3fd36e5f93
4 changed files with 268 additions and 32 deletions
|
|
@ -55,6 +55,7 @@ import android.util.Log;
|
|||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.modules.utils.build.SdkLevel;
|
||||
import com.android.net.module.util.BitUtils;
|
||||
import com.android.net.module.util.CollectionUtils;
|
||||
import com.android.net.module.util.NetworkIdentityUtils;
|
||||
|
||||
|
|
@ -138,6 +139,10 @@ public final class NetworkTemplate implements Parcelable {
|
|||
*/
|
||||
public static final int NETWORK_TYPE_ALL = -1;
|
||||
|
||||
/** @hide */
|
||||
@VisibleForTesting
|
||||
public static final long TRANSPORT_TYPES_ALL = 0L;
|
||||
|
||||
/** @hide */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(prefix = { "OEM_MANAGED_" }, value = {
|
||||
|
|
@ -410,6 +415,8 @@ public final class NetworkTemplate implements Parcelable {
|
|||
// Bitfield containing OEM network properties{@code NetworkIdentity#OEM_*}.
|
||||
private final int mOemManaged;
|
||||
|
||||
private final long mTransportTypesBits;
|
||||
|
||||
private static void checkValidMatchSubscriberIds(int matchRule, String[] matchSubscriberIds) {
|
||||
switch (matchRule) {
|
||||
// CARRIER templates must always specify a valid subscriber ID.
|
||||
|
|
@ -459,7 +466,7 @@ public final class NetworkTemplate implements Parcelable {
|
|||
subscriberId != null ? new String[] { subscriberId } : new String[0],
|
||||
wifiNetworkKey != null ? new String[] { wifiNetworkKey } : new String[0],
|
||||
getMeterednessForBackwardsCompatibility(matchRule), ROAMING_ALL,
|
||||
DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL);
|
||||
DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL, TRANSPORT_TYPES_ALL);
|
||||
if (matchRule == 6 || matchRule == 7) {
|
||||
Log.e(TAG, "Use MATCH_MOBILE with empty subscriberIds or MATCH_WIFI with empty "
|
||||
+ "wifiNetworkKeys instead of template with matchRule=" + matchRule);
|
||||
|
|
@ -495,7 +502,7 @@ public final class NetworkTemplate implements Parcelable {
|
|||
wifiNetworkKey != null ? new String[] { wifiNetworkKey } : new String[0],
|
||||
getMeterednessForBackwardsCompatibility(matchRule),
|
||||
ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
|
||||
OEM_MANAGED_ALL);
|
||||
OEM_MANAGED_ALL, TRANSPORT_TYPES_ALL);
|
||||
// TODO : this is part of hidden-o txt, does that mean it should be annotated with
|
||||
// @UnsupportedAppUsage(maxTargetSdk = O) ? If yes, can't throwAtLeastU() lest apps
|
||||
// targeting O- crash on those devices.
|
||||
|
|
@ -512,14 +519,15 @@ public final class NetworkTemplate implements Parcelable {
|
|||
// subscriberIds.
|
||||
this(getBackwardsCompatibleMatchRule(matchRule),
|
||||
matchSubscriberIds == null ? new String[]{} : matchSubscriberIds,
|
||||
matchWifiNetworkKeys, metered, roaming, defaultNetwork, ratType, oemManaged);
|
||||
matchWifiNetworkKeys, metered, roaming, defaultNetwork, ratType, oemManaged,
|
||||
TRANSPORT_TYPES_ALL);
|
||||
throwAtLeastU();
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public NetworkTemplate(int matchRule, String[] matchSubscriberIds,
|
||||
String[] matchWifiNetworkKeys, int metered, int roaming, int defaultNetwork,
|
||||
int ratType, int oemManaged) {
|
||||
int ratType, int oemManaged, long transportTypesBits) {
|
||||
Objects.requireNonNull(matchWifiNetworkKeys);
|
||||
Objects.requireNonNull(matchSubscriberIds);
|
||||
mMatchRule = matchRule;
|
||||
|
|
@ -530,6 +538,7 @@ public final class NetworkTemplate implements Parcelable {
|
|||
mDefaultNetwork = defaultNetwork;
|
||||
mRatType = ratType;
|
||||
mOemManaged = oemManaged;
|
||||
mTransportTypesBits = transportTypesBits;
|
||||
checkValidMatchSubscriberIds(matchRule, matchSubscriberIds);
|
||||
if (!isKnownMatchRule(matchRule)) {
|
||||
throw new IllegalArgumentException("Unknown network template rule " + matchRule
|
||||
|
|
@ -546,6 +555,7 @@ public final class NetworkTemplate implements Parcelable {
|
|||
mDefaultNetwork = in.readInt();
|
||||
mRatType = in.readInt();
|
||||
mOemManaged = in.readInt();
|
||||
mTransportTypesBits = in.readLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -558,6 +568,7 @@ public final class NetworkTemplate implements Parcelable {
|
|||
dest.writeInt(mDefaultNetwork);
|
||||
dest.writeInt(mRatType);
|
||||
dest.writeInt(mOemManaged);
|
||||
dest.writeLong(mTransportTypesBits);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -590,6 +601,9 @@ public final class NetworkTemplate implements Parcelable {
|
|||
if (mOemManaged != OEM_MANAGED_ALL) {
|
||||
builder.append(", oemManaged=").append(getOemManagedNames(mOemManaged));
|
||||
}
|
||||
if (mTransportTypesBits != TRANSPORT_TYPES_ALL) {
|
||||
builder.append(", transportTypes=").append(Arrays.toString(getTransportTypes()));
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
|
|
@ -597,7 +611,7 @@ public final class NetworkTemplate implements Parcelable {
|
|||
public int hashCode() {
|
||||
return Objects.hash(mMatchRule, Arrays.hashCode(mMatchSubscriberIds),
|
||||
Arrays.hashCode(mMatchWifiNetworkKeys), mMetered, mRoaming, mDefaultNetwork,
|
||||
mRatType, mOemManaged);
|
||||
mRatType, mOemManaged, mTransportTypesBits);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -611,7 +625,8 @@ public final class NetworkTemplate implements Parcelable {
|
|||
&& mRatType == other.mRatType
|
||||
&& mOemManaged == other.mOemManaged
|
||||
&& Arrays.equals(mMatchSubscriberIds, other.mMatchSubscriberIds)
|
||||
&& Arrays.equals(mMatchWifiNetworkKeys, other.mMatchWifiNetworkKeys);
|
||||
&& Arrays.equals(mMatchWifiNetworkKeys, other.mMatchWifiNetworkKeys)
|
||||
&& mTransportTypesBits == other.mTransportTypesBits;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -709,6 +724,16 @@ public final class NetworkTemplate implements Parcelable {
|
|||
return mRatType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the transport types filter of the template.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
public int[] getTransportTypes() {
|
||||
return BitUtils.unpackBits(mTransportTypesBits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the OEM managed filter of the template. See {@code OEM_MANAGED_*} or
|
||||
* {@code android.net.NetworkIdentity#OEM_*}.
|
||||
|
|
@ -730,7 +755,10 @@ public final class NetworkTemplate implements Parcelable {
|
|||
if (!matchesRoaming(ident)) return false;
|
||||
if (!matchesDefaultNetwork(ident)) return false;
|
||||
if (!matchesOemNetwork(ident)) return false;
|
||||
if (!matchesTransportTypes(ident)) return false;
|
||||
|
||||
// TODO: Convert match rule handling into transport type matches and
|
||||
// eliminate the need of legacy network types.
|
||||
switch (mMatchRule) {
|
||||
case MATCH_MOBILE:
|
||||
return matchesMobile(ident);
|
||||
|
|
@ -778,6 +806,13 @@ public final class NetworkTemplate implements Parcelable {
|
|||
|| (mOemManaged == ident.mOemManaged);
|
||||
}
|
||||
|
||||
private boolean matchesTransportTypes(NetworkIdentity ident) {
|
||||
if (this.mTransportTypesBits == TRANSPORT_TYPES_ALL) return true;
|
||||
// Otherwise, for a match, the identity must possess ALL transport types
|
||||
// specified in the template.
|
||||
return (this.mTransportTypesBits & ident.mTransportTypesBits) == this.mTransportTypesBits;
|
||||
}
|
||||
|
||||
private boolean matchesCollapsedRatType(NetworkIdentity ident) {
|
||||
return mRatType == NETWORK_TYPE_ALL
|
||||
|| NetworkStatsManager.getCollapsedRatType(mRatType)
|
||||
|
|
@ -1004,7 +1039,8 @@ public final class NetworkTemplate implements Parcelable {
|
|||
(template.mMatchRule == MATCH_MOBILE
|
||||
|| template.mMatchRule == MATCH_CARRIER)
|
||||
? METERED_YES : METERED_ALL,
|
||||
ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL);
|
||||
ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL,
|
||||
TRANSPORT_TYPES_ALL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1041,6 +1077,7 @@ public final class NetworkTemplate implements Parcelable {
|
|||
private int mRoaming;
|
||||
private int mDefaultNetwork;
|
||||
private int mRatType;
|
||||
private long mTransportTypesBits;
|
||||
|
||||
// Bitfield containing OEM network properties {@code NetworkIdentity#OEM_*}.
|
||||
private int mOemManaged;
|
||||
|
|
@ -1059,6 +1096,7 @@ public final class NetworkTemplate implements Parcelable {
|
|||
mDefaultNetwork = DEFAULT_NETWORK_ALL;
|
||||
mRatType = NETWORK_TYPE_ALL;
|
||||
mOemManaged = OEM_MANAGED_ALL;
|
||||
mTransportTypesBits = TRANSPORT_TYPES_ALL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1153,6 +1191,25 @@ public final class NetworkTemplate implements Parcelable {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the transport types filter for this template.
|
||||
*
|
||||
* - If the array is empty, matches any transport type (wildcard).
|
||||
* - If not empty, matches networks possessing ALL specified transport types.
|
||||
* For example, a set with {@code TRANSPORT_WIFI} and {@code TRANSPORT_VPN}
|
||||
* requires a network to have both.
|
||||
*
|
||||
* @param transportTypes The array of {@code NetworkCapabilities#TRANSPORT_*} constants.
|
||||
* An empty array acts as a wildcard for all transports.
|
||||
* @return This {@code Builder} for chaining.
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setTransportTypes(int[] transportTypes) {
|
||||
mTransportTypesBits = BitUtils.packBits(transportTypes);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the OEM managed filter.
|
||||
*
|
||||
|
|
@ -1203,7 +1260,7 @@ public final class NetworkTemplate implements Parcelable {
|
|||
return new NetworkTemplate(mMatchRule,
|
||||
mMatchSubscriberIds.toArray(new String[0]),
|
||||
mMatchWifiNetworkKeys.toArray(new String[0]), mMetered, mRoaming,
|
||||
mDefaultNetwork, mRatType, mOemManaged);
|
||||
mDefaultNetwork, mRatType, mOemManaged, mTransportTypesBits);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,11 @@
|
|||
|
||||
package android.net.netstats
|
||||
|
||||
import android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH
|
||||
import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
|
||||
import android.net.NetworkCapabilities.TRANSPORT_ETHERNET
|
||||
import android.net.NetworkCapabilities.TRANSPORT_SATELLITE
|
||||
import android.net.NetworkCapabilities.TRANSPORT_WIFI
|
||||
import android.net.NetworkStats.DEFAULT_NETWORK_ALL
|
||||
import android.net.NetworkStats.METERED_ALL
|
||||
import android.net.NetworkStats.METERED_YES
|
||||
|
|
@ -30,6 +35,7 @@ import android.net.NetworkTemplate.MATCH_PROXY
|
|||
import android.net.NetworkTemplate.MATCH_WIFI
|
||||
import android.net.NetworkTemplate.NETWORK_TYPE_ALL
|
||||
import android.net.NetworkTemplate.OEM_MANAGED_ALL
|
||||
import android.net.NetworkTemplate.TRANSPORT_TYPES_ALL
|
||||
import android.os.Build
|
||||
import android.telephony.TelephonyManager
|
||||
import com.android.testutils.ConnectivityModuleTest
|
||||
|
|
@ -74,7 +80,8 @@ class NetworkTemplateTest {
|
|||
ROAMING_ALL,
|
||||
DEFAULT_NETWORK_ALL,
|
||||
NETWORK_TYPE_ALL,
|
||||
OEM_MANAGED_ALL
|
||||
OEM_MANAGED_ALL,
|
||||
TRANSPORT_TYPES_ALL
|
||||
)
|
||||
assertEquals(expectedTemplate, it)
|
||||
}
|
||||
|
|
@ -93,7 +100,8 @@ class NetworkTemplateTest {
|
|||
ROAMING_YES,
|
||||
DEFAULT_NETWORK_ALL,
|
||||
NETWORK_TYPE_ALL,
|
||||
OEM_MANAGED_ALL
|
||||
OEM_MANAGED_ALL,
|
||||
TRANSPORT_TYPES_ALL
|
||||
)
|
||||
assertEquals(expectedTemplate, it)
|
||||
}
|
||||
|
|
@ -123,7 +131,8 @@ class NetworkTemplateTest {
|
|||
ROAMING_ALL,
|
||||
DEFAULT_NETWORK_ALL,
|
||||
NETWORK_TYPE_ALL,
|
||||
OEM_MANAGED_ALL
|
||||
OEM_MANAGED_ALL,
|
||||
TRANSPORT_TYPES_ALL
|
||||
)
|
||||
assertEquals(expectedTemplate, it)
|
||||
}
|
||||
|
|
@ -140,7 +149,8 @@ class NetworkTemplateTest {
|
|||
ROAMING_ALL,
|
||||
DEFAULT_NETWORK_ALL,
|
||||
NETWORK_TYPE_ALL,
|
||||
OEM_MANAGED_ALL
|
||||
OEM_MANAGED_ALL,
|
||||
TRANSPORT_TYPES_ALL
|
||||
)
|
||||
assertEquals(expectedTemplate, it)
|
||||
}
|
||||
|
|
@ -157,7 +167,8 @@ class NetworkTemplateTest {
|
|||
ROAMING_ALL,
|
||||
DEFAULT_NETWORK_ALL,
|
||||
TelephonyManager.NETWORK_TYPE_UMTS,
|
||||
OEM_MANAGED_ALL
|
||||
OEM_MANAGED_ALL,
|
||||
TRANSPORT_TYPES_ALL
|
||||
)
|
||||
assertEquals(expectedTemplate, it)
|
||||
}
|
||||
|
|
@ -173,7 +184,8 @@ class NetworkTemplateTest {
|
|||
ROAMING_ALL,
|
||||
DEFAULT_NETWORK_ALL,
|
||||
NETWORK_TYPE_ALL,
|
||||
OEM_MANAGED_ALL
|
||||
OEM_MANAGED_ALL,
|
||||
TRANSPORT_TYPES_ALL
|
||||
)
|
||||
assertEquals(expectedTemplate, it)
|
||||
}
|
||||
|
|
@ -190,7 +202,8 @@ class NetworkTemplateTest {
|
|||
ROAMING_ALL,
|
||||
DEFAULT_NETWORK_ALL,
|
||||
NETWORK_TYPE_ALL,
|
||||
OEM_MANAGED_ALL
|
||||
OEM_MANAGED_ALL,
|
||||
TRANSPORT_TYPES_ALL
|
||||
)
|
||||
assertEquals(expectedTemplate, it)
|
||||
}
|
||||
|
|
@ -207,7 +220,8 @@ class NetworkTemplateTest {
|
|||
ROAMING_ALL,
|
||||
DEFAULT_NETWORK_ALL,
|
||||
NETWORK_TYPE_ALL,
|
||||
OEM_MANAGED_ALL
|
||||
OEM_MANAGED_ALL,
|
||||
TRANSPORT_TYPES_ALL
|
||||
)
|
||||
assertEquals(expectedTemplate, it)
|
||||
}
|
||||
|
|
@ -224,7 +238,8 @@ class NetworkTemplateTest {
|
|||
ROAMING_ALL,
|
||||
DEFAULT_NETWORK_ALL,
|
||||
NETWORK_TYPE_ALL,
|
||||
OEM_MANAGED_ALL
|
||||
OEM_MANAGED_ALL,
|
||||
TRANSPORT_TYPES_ALL
|
||||
)
|
||||
assertEquals(expectedTemplate, it)
|
||||
}
|
||||
|
|
@ -273,9 +288,34 @@ class NetworkTemplateTest {
|
|||
ROAMING_ALL,
|
||||
DEFAULT_NETWORK_ALL,
|
||||
NETWORK_TYPE_ALL,
|
||||
OEM_MANAGED_ALL
|
||||
OEM_MANAGED_ALL,
|
||||
TRANSPORT_TYPES_ALL
|
||||
)
|
||||
assertEquals(expectedTemplate, it)
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the builder does not throw, and transports read from the getter is expected.
|
||||
@Test
|
||||
fun testBuilderTransportTypes() {
|
||||
assertGetSetTransportTypes(MATCH_MOBILE, TRANSPORT_CELLULAR)
|
||||
assertGetSetTransportTypes(MATCH_MOBILE, TRANSPORT_SATELLITE)
|
||||
assertGetSetTransportTypes(MATCH_WIFI, TRANSPORT_WIFI)
|
||||
assertGetSetTransportTypes(MATCH_ETHERNET, TRANSPORT_ETHERNET)
|
||||
assertGetSetTransportTypes(MATCH_BLUETOOTH, TRANSPORT_BLUETOOTH)
|
||||
assertGetSetTransportTypes(MATCH_PROXY, TRANSPORT_BLUETOOTH)
|
||||
assertGetSetTransportTypes(MATCH_CARRIER, TRANSPORT_CELLULAR)
|
||||
assertGetSetTransportTypes(MATCH_CARRIER, TRANSPORT_WIFI)
|
||||
}
|
||||
|
||||
private fun assertGetSetTransportTypes(matchRule: Int, transport: Int) {
|
||||
val builder = NetworkTemplate.Builder(matchRule)
|
||||
.setTransportTypes(intArrayOf(transport))
|
||||
if (matchRule == MATCH_CARRIER) {
|
||||
builder.setSubscriberIds(setOf(TEST_IMSI1))
|
||||
}
|
||||
val template = builder.build()
|
||||
assertEquals(1, template.transportTypes.size)
|
||||
assertEquals(transport, template.transportTypes[0])
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,10 @@ import android.content.Context
|
|||
import android.net.ConnectivityManager.TYPE_MOBILE
|
||||
import android.net.ConnectivityManager.TYPE_TEST
|
||||
import android.net.ConnectivityManager.TYPE_WIFI
|
||||
import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
|
||||
import android.net.NetworkCapabilities.TRANSPORT_SATELLITE
|
||||
import android.net.NetworkCapabilities.TRANSPORT_TEST
|
||||
import android.net.NetworkCapabilities.TRANSPORT_VPN
|
||||
import android.net.NetworkCapabilities.TRANSPORT_WIFI
|
||||
import android.net.NetworkIdentity.OEM_NONE
|
||||
import android.net.NetworkIdentity.OEM_PAID
|
||||
|
|
@ -40,6 +43,7 @@ import android.net.NetworkTemplate.NETWORK_TYPE_ALL
|
|||
import android.net.NetworkTemplate.OEM_MANAGED_ALL
|
||||
import android.net.NetworkTemplate.OEM_MANAGED_NO
|
||||
import android.net.NetworkTemplate.OEM_MANAGED_YES
|
||||
import android.net.NetworkTemplate.TRANSPORT_TYPES_ALL
|
||||
import android.net.NetworkTemplate.buildTemplateMobileAll
|
||||
import android.net.NetworkTemplate.buildTemplateMobileWildcard
|
||||
import android.net.NetworkTemplate.buildTemplateWifiWildcard
|
||||
|
|
@ -47,6 +51,7 @@ import android.net.NetworkTemplate.normalize
|
|||
import android.net.wifi.WifiInfo
|
||||
import android.os.Build
|
||||
import android.telephony.TelephonyManager
|
||||
import com.android.net.module.util.BitUtils
|
||||
import com.android.testutils.DevSdkIgnoreRule
|
||||
import com.android.testutils.DevSdkIgnoreRunner
|
||||
import com.android.testutils.NonNullTestUtils
|
||||
|
|
@ -93,7 +98,8 @@ class NetworkTemplateTest {
|
|||
subscriberId: String? = null,
|
||||
wifiKey: String? = null,
|
||||
oemManaged: Int = OEM_NONE,
|
||||
metered: Boolean = true
|
||||
metered: Boolean = true,
|
||||
transportTypes: IntArray = intArrayOf(),
|
||||
): NetworkStateSnapshot {
|
||||
`when`(mockWifiInfo.getNetworkKey()).thenReturn(wifiKey)
|
||||
val lp = LinkProperties()
|
||||
|
|
@ -108,6 +114,7 @@ class NetworkTemplateTest {
|
|||
NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE,
|
||||
(oemManaged and OEM_PRIVATE) == OEM_PRIVATE
|
||||
)
|
||||
setTransportTypes(transportTypes)
|
||||
if (type == TYPE_TEST) {
|
||||
wifiKey?.let { TestNetworkSpecifier(it) }?.let {
|
||||
// Must have a single non-test transport specified to use setNetworkSpecifier.
|
||||
|
|
@ -193,7 +200,8 @@ class NetworkTemplateTest {
|
|||
ROAMING_ALL,
|
||||
DEFAULT_NETWORK_ALL,
|
||||
NETWORK_TYPE_ALL,
|
||||
OEM_MANAGED_ALL
|
||||
OEM_MANAGED_ALL,
|
||||
TRANSPORT_TYPES_ALL
|
||||
)
|
||||
|
||||
val identMobile1 = buildNetworkIdentity(
|
||||
|
|
@ -676,6 +684,7 @@ class NetworkTemplateTest {
|
|||
fun testEquals() {
|
||||
val templateImsi1 = NetworkTemplate.Builder(MATCH_MOBILE).setMeteredness(METERED_YES)
|
||||
.setSubscriberIds(setOf(TEST_IMSI1)).setRatType(TelephonyManager.NETWORK_TYPE_UMTS)
|
||||
.setTransportTypes(intArrayOf(TRANSPORT_SATELLITE, TRANSPORT_VPN))
|
||||
.build()
|
||||
val dupTemplateImsi1 = NetworkTemplate(
|
||||
MATCH_MOBILE,
|
||||
|
|
@ -685,7 +694,8 @@ class NetworkTemplateTest {
|
|||
ROAMING_ALL,
|
||||
DEFAULT_NETWORK_ALL,
|
||||
TelephonyManager.NETWORK_TYPE_UMTS,
|
||||
OEM_MANAGED_ALL
|
||||
OEM_MANAGED_ALL,
|
||||
BitUtils.packBits(intArrayOf(TRANSPORT_SATELLITE, TRANSPORT_VPN))
|
||||
)
|
||||
val templateImsi2 = NetworkTemplate.Builder(MATCH_MOBILE).setMeteredness(METERED_YES)
|
||||
.setSubscriberIds(setOf(TEST_IMSI2)).setRatType(TelephonyManager.NETWORK_TYPE_UMTS)
|
||||
|
|
@ -696,7 +706,9 @@ class NetworkTemplateTest {
|
|||
assertNotEquals(templateImsi1, templateImsi2)
|
||||
|
||||
val templateWifiKey1 = NetworkTemplate.Builder(MATCH_WIFI)
|
||||
.setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build()
|
||||
.setWifiNetworkKeys(setOf(TEST_WIFI_KEY1))
|
||||
.setTransportTypes(intArrayOf(TRANSPORT_WIFI))
|
||||
.build()
|
||||
val dupTemplateWifiKey1 = NetworkTemplate(
|
||||
MATCH_WIFI,
|
||||
emptyArray<String>(),
|
||||
|
|
@ -705,7 +717,8 @@ class NetworkTemplateTest {
|
|||
ROAMING_ALL,
|
||||
DEFAULT_NETWORK_ALL,
|
||||
NETWORK_TYPE_ALL,
|
||||
OEM_MANAGED_ALL
|
||||
OEM_MANAGED_ALL,
|
||||
BitUtils.packBits(intArrayOf(TRANSPORT_WIFI))
|
||||
)
|
||||
val templateWifiKey2 = NetworkTemplate.Builder(MATCH_WIFI)
|
||||
.setWifiNetworkKeys(setOf(TEST_WIFI_KEY2)).build()
|
||||
|
|
@ -725,7 +738,8 @@ class NetworkTemplateTest {
|
|||
ROAMING_ALL,
|
||||
DEFAULT_NETWORK_ALL,
|
||||
TelephonyManager.NETWORK_TYPE_LTE,
|
||||
OEM_MANAGED_ALL
|
||||
OEM_MANAGED_ALL,
|
||||
0x12345678L
|
||||
)
|
||||
val templateWifi = NetworkTemplate(
|
||||
MATCH_WIFI,
|
||||
|
|
@ -735,7 +749,8 @@ class NetworkTemplateTest {
|
|||
ROAMING_ALL,
|
||||
DEFAULT_NETWORK_ALL,
|
||||
0,
|
||||
OEM_MANAGED_ALL
|
||||
OEM_MANAGED_ALL,
|
||||
0xDEADBEEFL
|
||||
)
|
||||
val templateOem = NetworkTemplate(
|
||||
MATCH_MOBILE,
|
||||
|
|
@ -745,11 +760,12 @@ class NetworkTemplateTest {
|
|||
ROAMING_ALL,
|
||||
DEFAULT_NETWORK_ALL,
|
||||
0,
|
||||
OEM_MANAGED_YES
|
||||
OEM_MANAGED_YES,
|
||||
0xFFFFFFFFL
|
||||
)
|
||||
assertParcelSane(templateMobile, 8)
|
||||
assertParcelSane(templateWifi, 8)
|
||||
assertParcelSane(templateOem, 8)
|
||||
assertParcelSane(templateMobile, 9)
|
||||
assertParcelSane(templateWifi, 9)
|
||||
assertParcelSane(templateOem, 9)
|
||||
}
|
||||
|
||||
// Verify NETWORK_TYPE_* constants in NetworkTemplate do not conflict with
|
||||
|
|
@ -818,7 +834,8 @@ class NetworkTemplateTest {
|
|||
ROAMING_ALL,
|
||||
DEFAULT_NETWORK_ALL,
|
||||
NETWORK_TYPE_ALL,
|
||||
OEM_MANAGED_YES
|
||||
OEM_MANAGED_YES,
|
||||
TRANSPORT_TYPES_ALL
|
||||
)
|
||||
val templateOemAll = NetworkTemplate(
|
||||
matchType,
|
||||
|
|
@ -828,7 +845,8 @@ class NetworkTemplateTest {
|
|||
ROAMING_ALL,
|
||||
DEFAULT_NETWORK_ALL,
|
||||
NETWORK_TYPE_ALL,
|
||||
OEM_MANAGED_ALL
|
||||
OEM_MANAGED_ALL,
|
||||
TRANSPORT_TYPES_ALL
|
||||
)
|
||||
|
||||
for (identityOemManagedState in oemManagedStates) {
|
||||
|
|
@ -854,7 +872,8 @@ class NetworkTemplateTest {
|
|||
ROAMING_ALL,
|
||||
DEFAULT_NETWORK_ALL,
|
||||
NETWORK_TYPE_ALL,
|
||||
templateOemManagedState
|
||||
templateOemManagedState,
|
||||
TRANSPORT_TYPES_ALL
|
||||
)
|
||||
if (identityOemManagedState == templateOemManagedState) {
|
||||
template.assertMatches(ident)
|
||||
|
|
@ -886,6 +905,54 @@ class NetworkTemplateTest {
|
|||
matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI, identWifiKey = TEST_WIFI_KEY1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTransportTypesMatches() {
|
||||
val identSatellite = NetworkIdentity.Builder()
|
||||
.setType(TYPE_MOBILE)
|
||||
.setTransportTypes(setOf(TRANSPORT_SATELLITE))
|
||||
.build()
|
||||
val identMobileVpn = NetworkIdentity.Builder()
|
||||
.setType(TYPE_MOBILE)
|
||||
.setTransportTypes(setOf(TRANSPORT_CELLULAR, TRANSPORT_VPN))
|
||||
.build()
|
||||
val identOnlyCellular = NetworkIdentity.Builder()
|
||||
.setType(TYPE_MOBILE)
|
||||
.setTransportTypes(setOf(TRANSPORT_CELLULAR))
|
||||
.build()
|
||||
|
||||
val templateMobileNoTransport = NetworkTemplate.Builder(MATCH_MOBILE)
|
||||
.build() // Wildcard for transports
|
||||
val templateMobileWithCellularTransport = NetworkTemplate.Builder(MATCH_MOBILE)
|
||||
.setTransportTypes(intArrayOf(TRANSPORT_CELLULAR))
|
||||
.build()
|
||||
val templateSatellite = NetworkTemplate.Builder(MATCH_MOBILE)
|
||||
.setTransportTypes(intArrayOf(TRANSPORT_SATELLITE))
|
||||
.build()
|
||||
val templateVpnAndCellular = NetworkTemplate.Builder(MATCH_MOBILE)
|
||||
.setTransportTypes(intArrayOf(TRANSPORT_VPN, TRANSPORT_CELLULAR))
|
||||
.build()
|
||||
|
||||
// 1. Mobile wildcard template
|
||||
templateMobileNoTransport.assertMatches(identSatellite)
|
||||
templateMobileNoTransport.assertMatches(identMobileVpn)
|
||||
templateMobileNoTransport.assertMatches(identOnlyCellular)
|
||||
|
||||
// 2. Template requiring TRANSPORT_CELLULAR
|
||||
templateMobileWithCellularTransport.assertDoesNotMatch(identSatellite)
|
||||
templateMobileWithCellularTransport.assertMatches(identMobileVpn)
|
||||
templateMobileWithCellularTransport.assertMatches(identOnlyCellular)
|
||||
|
||||
// 3. Template requiring TRANSPORT_SATELLITE
|
||||
templateSatellite.assertMatches(identSatellite)
|
||||
templateSatellite.assertDoesNotMatch(identMobileVpn)
|
||||
templateSatellite.assertDoesNotMatch(identOnlyCellular)
|
||||
|
||||
// 4. Template requiring TRANSPORT_VPN AND TRANSPORT_CELLULAR
|
||||
templateVpnAndCellular.assertDoesNotMatch(identSatellite)
|
||||
templateVpnAndCellular.assertMatches(identMobileVpn)
|
||||
templateVpnAndCellular.assertDoesNotMatch(identOnlyCellular)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNormalize() {
|
||||
var mergedImsiList = arrayOf(TEST_IMSI1, TEST_IMSI2)
|
||||
|
|
|
|||
|
|
@ -1535,6 +1535,78 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
|||
|
||||
}
|
||||
|
||||
// This test demonstrates that a network identity with legacy type TYPE_MOBILE
|
||||
// can represent different underlying physical transports (e.g., satellite or cellular).
|
||||
// NetworkTemplate, using MATCH_MOBILE, can then differentiate these further
|
||||
// by applying a transportTypes filter.
|
||||
@Test
|
||||
public void testGetSatelliteStats() throws Exception {
|
||||
mockDefaultSettings();
|
||||
final NetworkTemplate templateSatellite =
|
||||
new NetworkTemplate.Builder(MATCH_MOBILE)
|
||||
.setMeteredness(METERED_YES)
|
||||
.setSubscriberIds(Set.of(IMSI_1))
|
||||
.setTransportTypes(new int[]{NetworkCapabilities.TRANSPORT_SATELLITE})
|
||||
.build();
|
||||
|
||||
final NetworkTemplate templateCellularOnly =
|
||||
new NetworkTemplate.Builder(MATCH_MOBILE)
|
||||
.setMeteredness(METERED_YES)
|
||||
.setSubscriberIds(Set.of(IMSI_1))
|
||||
.setTransportTypes(new int[]{NetworkCapabilities.TRANSPORT_CELLULAR})
|
||||
.build();
|
||||
|
||||
// Initial state: Assert all relevant templates are empty
|
||||
assertUidTotal(sTemplateImsi1, UID_RED, 0L, 0L, 0L, 0L, 0);
|
||||
assertUidTotal(templateSatellite, UID_RED, 0L, 0L, 0L, 0L, 0);
|
||||
assertUidTotal(templateCellularOnly, UID_RED, 0L, 0L, 0L, 0L, 0);
|
||||
|
||||
// 1. Bring up SATELLITE mobile network for IMSI_1
|
||||
NetworkStateSnapshot satelliteState = buildSatelliteMobileState(IMSI_1);
|
||||
|
||||
mService.notifyNetworkStatus(NETWORKS_MOBILE, new NetworkStateSnapshot[]{satelliteState},
|
||||
getActiveIface(satelliteState), new UnderlyingNetworkInfo[0]);
|
||||
setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_LTE);
|
||||
|
||||
// Record 100 bytes of data on the satellite network for UID_RED
|
||||
incrementCurrentTime(HOUR_IN_MILLIS);
|
||||
mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
|
||||
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
|
||||
DEFAULT_NETWORK_YES, 100L, 10L, 100L, 10L, 0L));
|
||||
forcePollAndWaitForIdle();
|
||||
|
||||
// Verify data attribution for SATELLITE
|
||||
// sTemplateImsi1 (general mobile) should count satellite data.
|
||||
assertUidTotal(sTemplateImsi1, UID_RED, 100L, 10L, 100L, 10L, 0);
|
||||
// sTemplateMobileSatelliteImsi1 (satellite specific) should count satellite data.
|
||||
assertUidTotal(templateSatellite, UID_RED, 100L, 10L, 100L, 10L, 0);
|
||||
// templateCellularOnly (cellular specific) should NOT count satellite data.
|
||||
assertUidTotal(templateCellularOnly, UID_RED, 0L, 0L, 0L, 0L, 0);
|
||||
|
||||
// 2. Switch to CELLULAR mobile network for IMSI_1 on the same interface
|
||||
NetworkStateSnapshot cellularState = buildMobileState(IMSI_1);
|
||||
|
||||
mService.notifyNetworkStatus(NETWORKS_MOBILE, new NetworkStateSnapshot[]{cellularState},
|
||||
getActiveIface(cellularState), new UnderlyingNetworkInfo[0]);
|
||||
// Mocking UID details to reflect total traffic on the interface since boot/last poll.
|
||||
// Previous satellite data (100B) + new cellular data (200B) = 300B total on iface.
|
||||
incrementCurrentTime(HOUR_IN_MILLIS);
|
||||
mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
|
||||
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
|
||||
DEFAULT_NETWORK_YES, 300L, 30L, 300L, 30L, 0L)); // 100sat + 200cell
|
||||
forcePollAndWaitForIdle();
|
||||
|
||||
// Verify data attribution after CELLULAR usage
|
||||
// sTemplateImsi1 (general mobile) should count cumulative data (satellite + cellular).
|
||||
// (100 previous + 200 new = 300 total)
|
||||
assertUidTotal(sTemplateImsi1, UID_RED, 300L, 30L, 300L, 30L, 0);
|
||||
// sTemplateMobileSatelliteImsi1 should still only have the satellite data.
|
||||
assertUidTotal(templateSatellite, UID_RED, 100L, 10L, 100L, 10L, 0);
|
||||
// templateCellularOnly should now have the new cellular data (200B).
|
||||
// (Current total on iface 300B - previous total on iface before this poll 100B = 200B)
|
||||
assertUidTotal(templateCellularOnly, UID_RED, 200L, 20L, 200L, 20L, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForegroundBackground() throws Exception {
|
||||
// pretend that network comes online
|
||||
|
|
|
|||
Loading…
Reference in a new issue