Merge "Replace Preconditions.checkNotNull with Objects.requireNonNull"
diff --git a/framework-t/src/android/net/IpSecManager.java b/framework-t/src/android/net/IpSecManager.java
index ca9be1c..0d15dff 100644
--- a/framework-t/src/android/net/IpSecManager.java
+++ b/framework-t/src/android/net/IpSecManager.java
@@ -85,6 +85,7 @@
*
* @hide
*/
+ @SystemApi(client = MODULE_LIBRARIES)
public static final int DIRECTION_FWD = 2;
/**
diff --git a/framework-t/src/android/net/NetworkStats.java b/framework-t/src/android/net/NetworkStats.java
index c7ffc19..1986b83 100644
--- a/framework-t/src/android/net/NetworkStats.java
+++ b/framework-t/src/android/net/NetworkStats.java
@@ -16,7 +16,7 @@
package android.net;
-import static com.android.internal.net.NetworkUtilsInternal.multiplySafeByRational;
+import static com.android.net.module.util.NetworkStatsUtils.multiplySafeByRational;
import android.annotation.IntDef;
import android.annotation.NonNull;
diff --git a/framework-t/src/android/net/NetworkStatsCollection.java b/framework-t/src/android/net/NetworkStatsCollection.java
index 0d3b9ed..8d1347e 100644
--- a/framework-t/src/android/net/NetworkStatsCollection.java
+++ b/framework-t/src/android/net/NetworkStatsCollection.java
@@ -30,7 +30,7 @@
import static android.net.TrafficStats.UID_REMOVED;
import static android.text.format.DateUtils.WEEK_IN_MILLIS;
-import static com.android.internal.net.NetworkUtilsInternal.multiplySafeByRational;
+import static com.android.net.module.util.NetworkStatsUtils.multiplySafeByRational;
import android.os.Binder;
import android.service.NetworkStatsCollectionKeyProto;
diff --git a/framework-t/src/android/net/NetworkStatsHistory.java b/framework-t/src/android/net/NetworkStatsHistory.java
index a875e1a..3eef4ee 100644
--- a/framework-t/src/android/net/NetworkStatsHistory.java
+++ b/framework-t/src/android/net/NetworkStatsHistory.java
@@ -28,8 +28,8 @@
import static android.net.NetworkStatsHistory.ParcelUtils.writeLongArray;
import static android.text.format.DateUtils.SECOND_IN_MILLIS;
-import static com.android.internal.net.NetworkUtilsInternal.multiplySafeByRational;
import static com.android.internal.util.ArrayUtils.total;
+import static com.android.net.module.util.NetworkStatsUtils.multiplySafeByRational;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
diff --git a/framework-t/src/android/net/NetworkTemplate.java b/framework-t/src/android/net/NetworkTemplate.java
index 8b9c14d..d852913 100644
--- a/framework-t/src/android/net/NetworkTemplate.java
+++ b/framework-t/src/android/net/NetworkTemplate.java
@@ -24,6 +24,8 @@
import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
import static android.net.ConnectivityManager.TYPE_WIMAX;
import static android.net.NetworkIdentity.OEM_NONE;
+import static android.net.NetworkIdentity.OEM_PAID;
+import static android.net.NetworkIdentity.OEM_PRIVATE;
import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
import static android.net.NetworkStats.DEFAULT_NETWORK_YES;
@@ -35,6 +37,7 @@
import static android.net.NetworkStats.ROAMING_YES;
import static android.net.wifi.WifiInfo.sanitizeSsid;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
@@ -44,15 +47,21 @@
import android.telephony.Annotation.NetworkType;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
+import android.util.ArraySet;
import com.android.internal.util.ArrayUtils;
import com.android.net.module.util.NetworkIdentityUtils;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
/**
* Predicate used to match {@link NetworkIdentity}, usually when collecting
@@ -60,40 +69,88 @@
*
* @hide
*/
-public class NetworkTemplate implements Parcelable {
- private static final String TAG = "NetworkTemplate";
+// @SystemApi(client = MODULE_LIBRARIES)
+public final class NetworkTemplate implements Parcelable {
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = { "MATCH_" }, value = {
+ MATCH_MOBILE,
+ MATCH_WIFI,
+ MATCH_ETHERNET,
+ MATCH_BLUETOOTH,
+ MATCH_CARRIER
+ })
+ public @interface TemplateMatchRule{}
+ /** Match rule to match cellular networks with given Subscriber Ids. */
public static final int MATCH_MOBILE = 1;
+ /** Match rule to match wifi networks. */
public static final int MATCH_WIFI = 4;
+ /** Match rule to match ethernet networks. */
public static final int MATCH_ETHERNET = 5;
+ /**
+ * Match rule to match all cellular networks.
+ *
+ * @hide
+ */
public static final int MATCH_MOBILE_WILDCARD = 6;
+ /**
+ * Match rule to match all wifi networks.
+ *
+ * @hide
+ */
public static final int MATCH_WIFI_WILDCARD = 7;
+ /** Match rule to match bluetooth networks. */
public static final int MATCH_BLUETOOTH = 8;
+ /**
+ * Match rule to match networks with {@link Connectivity#TYPE_PROXY} as the legacy network type.
+ *
+ * @hide
+ */
public static final int MATCH_PROXY = 9;
+ /**
+ * Match rule to match all networks with subscriberId inside the template. Some carriers
+ * may offer non-cellular networks like WiFi, which will be matched by this rule.
+ */
public static final int MATCH_CARRIER = 10;
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = { "SUBSCRIBER_ID_MATCH_RULE_" }, value = {
+ SUBSCRIBER_ID_MATCH_RULE_EXACT,
+ SUBSCRIBER_ID_MATCH_RULE_ALL
+ })
+ public @interface SubscriberIdMatchRule{}
/**
* Value of the match rule of the subscriberId to match networks with specific subscriberId.
+ *
+ * @hide
*/
public static final int SUBSCRIBER_ID_MATCH_RULE_EXACT = 0;
/**
* Value of the match rule of the subscriberId to match networks with any subscriberId which
* includes null and non-null.
+ *
+ * @hide
*/
public static final int SUBSCRIBER_ID_MATCH_RULE_ALL = 1;
- /**
- * Wi-Fi Network ID is never supposed to be null (if it is, it is a bug that
- * should be fixed), so it's not possible to want to match null vs
- * non-null. Therefore it's fine to use null as a sentinel for Network ID.
- */
+ // TODO: Remove this and replace all callers with WIFI_NETWORK_KEY_ALL.
+ /** @hide */
public static final String WIFI_NETWORKID_ALL = null;
/**
+ * Wi-Fi Network Key is never supposed to be null (if it is, it is a bug that
+ * should be fixed), so it's not possible to want to match null vs
+ * non-null. Therefore it's fine to use null as a sentinel for Wifi Network Key.
+ *
+ * @hide
+ */
+ public static final String WIFI_NETWORK_KEY_ALL = WIFI_NETWORKID_ALL;
+
+ /**
* Include all network types when filtering. This is meant to merge in with the
* {@code TelephonyManager.NETWORK_TYPE_*} constants, and thus needs to stay in sync.
- *
- * @hide
*/
public static final int NETWORK_TYPE_ALL = -1;
/**
@@ -106,21 +163,37 @@
*/
public static final int NETWORK_TYPE_5G_NSA = -2;
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = { "OEM_MANAGED_" }, value = {
+ OEM_MANAGED_ALL,
+ OEM_MANAGED_NO,
+ OEM_MANAGED_YES,
+ OEM_MANAGED_PAID,
+ OEM_MANAGED_PRIVATE
+ })
+ public @interface OemManaged{}
+
/**
* Value to match both OEM managed and unmanaged networks (all networks).
- * @hide
*/
public static final int OEM_MANAGED_ALL = -1;
/**
* Value to match networks which are not OEM managed.
- * @hide
*/
public static final int OEM_MANAGED_NO = OEM_NONE;
/**
* Value to match any OEM managed network.
- * @hide
*/
public static final int OEM_MANAGED_YES = -2;
+ /**
+ * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PAID}.
+ */
+ public static final int OEM_MANAGED_PAID = OEM_PAID;
+ /**
+ * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PRIVATE}.
+ */
+ public static final int OEM_MANAGED_PRIVATE = OEM_PRIVATE;
private static boolean isKnownMatchRule(final int rule) {
switch (rule) {
@@ -142,6 +215,8 @@
/**
* Template to match {@link ConnectivityManager#TYPE_MOBILE} networks with
* the given IMSI.
+ *
+ * @hide
*/
@UnsupportedAppUsage
public static NetworkTemplate buildTemplateMobileAll(String subscriberId) {
@@ -152,6 +227,8 @@
* Template to match cellular networks with the given IMSI, {@code ratType} and
* {@code metered}. Use {@link #NETWORK_TYPE_ALL} to include all network types when
* filtering. See {@code TelephonyManager.NETWORK_TYPE_*}.
+ *
+ * @hide
*/
public static NetworkTemplate buildTemplateMobileWithRatType(@Nullable String subscriberId,
@NetworkType int ratType, int metered) {
@@ -168,6 +245,8 @@
/**
* Template to match metered {@link ConnectivityManager#TYPE_MOBILE} networks,
* regardless of IMSI.
+ *
+ * @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public static NetworkTemplate buildTemplateMobileWildcard() {
@@ -177,6 +256,8 @@
/**
* Template to match all metered {@link ConnectivityManager#TYPE_WIFI} networks,
* regardless of SSID.
+ *
+ * @hide
*/
@UnsupportedAppUsage
public static NetworkTemplate buildTemplateWifiWildcard() {
@@ -185,6 +266,7 @@
return new NetworkTemplate(MATCH_WIFI_WILDCARD, null, null);
}
+ /** @hide */
@Deprecated
@UnsupportedAppUsage
public static NetworkTemplate buildTemplateWifi() {
@@ -194,6 +276,8 @@
/**
* Template to match {@link ConnectivityManager#TYPE_WIFI} networks with the
* given SSID.
+ *
+ * @hide
*/
public static NetworkTemplate buildTemplateWifi(@NonNull String networkId) {
Objects.requireNonNull(networkId);
@@ -208,7 +292,10 @@
* Template to match all {@link ConnectivityManager#TYPE_WIFI} networks with the given SSID,
* and IMSI.
*
- * Call with {@link #WIFI_NETWORKID_ALL} for {@code networkId} to get result regardless of SSID.
+ * Call with {@link #WIFI_NETWORK_KEY_ALL} for {@code networkId} to get result regardless
+ * of SSID.
+ *
+ * @hide
*/
public static NetworkTemplate buildTemplateWifi(@Nullable String networkId,
@Nullable String subscriberId) {
@@ -221,6 +308,8 @@
/**
* Template to combine all {@link ConnectivityManager#TYPE_ETHERNET} style
* networks together.
+ *
+ * @hide
*/
@UnsupportedAppUsage
public static NetworkTemplate buildTemplateEthernet() {
@@ -230,6 +319,8 @@
/**
* Template to combine all {@link ConnectivityManager#TYPE_BLUETOOTH} style
* networks together.
+ *
+ * @hide
*/
public static NetworkTemplate buildTemplateBluetooth() {
return new NetworkTemplate(MATCH_BLUETOOTH, null, null);
@@ -238,6 +329,8 @@
/**
* Template to combine all {@link ConnectivityManager#TYPE_PROXY} style
* networks together.
+ *
+ * @hide
*/
public static NetworkTemplate buildTemplateProxy() {
return new NetworkTemplate(MATCH_PROXY, null, null);
@@ -245,6 +338,8 @@
/**
* Template to match all metered carrier networks with the given IMSI.
+ *
+ * @hide
*/
public static NetworkTemplate buildTemplateCarrierMetered(@NonNull String subscriberId) {
Objects.requireNonNull(subscriberId);
@@ -267,6 +362,7 @@
*/
private final String[] mMatchSubscriberIds;
+ // TODO: Change variable name to match the Api surface.
private final String mNetworkId;
// Matches for the NetworkStats constants METERED_*, ROAMING_* and DEFAULT_NETWORK_*.
@@ -283,14 +379,14 @@
// Bitfield containing OEM network properties{@code NetworkIdentity#OEM_*}.
private final int mOemManaged;
- private void checkValidSubscriberIdMatchRule() {
- switch (mMatchRule) {
+ private static void checkValidSubscriberIdMatchRule(int matchRule, int subscriberIdMatchRule) {
+ switch (matchRule) {
case MATCH_MOBILE:
case MATCH_CARRIER:
// MOBILE and CARRIER templates must always specify a subscriber ID.
- if (mSubscriberIdMatchRule == SUBSCRIBER_ID_MATCH_RULE_ALL) {
- throw new IllegalArgumentException("Invalid SubscriberIdMatchRule"
- + "on match rule: " + getMatchRuleName(mMatchRule));
+ if (subscriberIdMatchRule == SUBSCRIBER_ID_MATCH_RULE_ALL) {
+ throw new IllegalArgumentException("Invalid SubscriberIdMatchRule "
+ + "on match rule: " + getMatchRuleName(matchRule));
}
return;
default:
@@ -298,12 +394,14 @@
}
}
+ /** @hide */
// TODO: Deprecate this constructor, mark it @UnsupportedAppUsage(maxTargetSdk = S)
@UnsupportedAppUsage
public NetworkTemplate(int matchRule, String subscriberId, String networkId) {
this(matchRule, subscriberId, new String[] { subscriberId }, networkId);
}
+ /** @hide */
public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
String networkId) {
// Older versions used to only match MATCH_MOBILE and MATCH_MOBILE_WILDCARD templates
@@ -316,6 +414,7 @@
OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT);
}
+ /** @hide */
// TODO: Remove it after updating all of the caller.
public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
String networkId, int metered, int roaming, int defaultNetwork, int subType,
@@ -324,6 +423,7 @@
defaultNetwork, subType, oemManaged, SUBSCRIBER_ID_MATCH_RULE_EXACT);
}
+ /** @hide */
public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
String networkId, int metered, int roaming, int defaultNetwork, int subType,
int oemManaged, int subscriberIdMatchRule) {
@@ -339,7 +439,7 @@
mSubType = subType;
mOemManaged = oemManaged;
mSubscriberIdMatchRule = subscriberIdMatchRule;
- checkValidSubscriberIdMatchRule();
+ checkValidSubscriberIdMatchRule(matchRule, subscriberIdMatchRule);
if (!isKnownMatchRule(matchRule)) {
throw new IllegalArgumentException("Unknown network template rule " + matchRule
+ " will not match any identity.");
@@ -360,7 +460,7 @@
}
@Override
- public void writeToParcel(Parcel dest, int flags) {
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mMatchRule);
dest.writeString(mSubscriberId);
dest.writeStringArray(mMatchSubscriberIds);
@@ -437,7 +537,7 @@
return false;
}
- private String subscriberIdMatchRuleToString(int rule) {
+ private static String subscriberIdMatchRuleToString(int rule) {
switch (rule) {
case SUBSCRIBER_ID_MATCH_RULE_EXACT:
return "EXACT_MATCH";
@@ -448,6 +548,7 @@
}
}
+ /** @hide */
public boolean isMatchRuleMobile() {
switch (mMatchRule) {
case MATCH_MOBILE:
@@ -458,48 +559,108 @@
}
}
- public boolean isPersistable() {
+ /**
+ * Get match rule of the template. See {@code MATCH_*}.
+ */
+ @UnsupportedAppUsage
+ public int getMatchRule() {
+ // Wildcard rules are not exposed. For external callers, convert wildcard rules to
+ // exposed rules before returning.
switch (mMatchRule) {
case MATCH_MOBILE_WILDCARD:
+ return MATCH_MOBILE;
case MATCH_WIFI_WILDCARD:
- return false;
- case MATCH_CARRIER:
- return mSubscriberId != null;
- case MATCH_WIFI:
- if (Objects.equals(mNetworkId, WIFI_NETWORKID_ALL)
- && mSubscriberIdMatchRule == SUBSCRIBER_ID_MATCH_RULE_ALL) {
- return false;
- }
- return true;
+ return MATCH_WIFI;
default:
- return true;
+ return mMatchRule;
}
}
- @UnsupportedAppUsage
- public int getMatchRule() {
- return mMatchRule;
- }
-
+ /**
+ * Get subscriber Id of the template.
+ */
+ @Nullable
@UnsupportedAppUsage
public String getSubscriberId() {
return mSubscriberId;
}
+ /**
+ * Get set of subscriber Ids of the template.
+ */
+ @NonNull
+ public Set<String> getSubscriberIds() {
+ return new ArraySet<>(Arrays.asList(mMatchSubscriberIds));
+ }
+
+ /**
+ * Get Wifi Network Key of the template. See {@link WifiInfo#getCurrentNetworkKey()}.
+ */
+ @Nullable
+ public String getWifiNetworkKey() {
+ return mNetworkId;
+ }
+
+ /** @hide */
+ // TODO: Remove this and replace all callers with {@link #getWifiNetworkKey()}.
+ @Nullable
public String getNetworkId() {
return mNetworkId;
}
+ /**
+ * Get Subscriber Id Match Rule of the template.
+ *
+ * @hide
+ */
public int getSubscriberIdMatchRule() {
return mSubscriberIdMatchRule;
}
+ /**
+ * Get meteredness filter of the template.
+ */
+ @NetworkStats.Meteredness
public int getMeteredness() {
return mMetered;
}
/**
+ * Get roaming filter of the template.
+ */
+ @NetworkStats.Roaming
+ public int getRoaming() {
+ return mRoaming;
+ }
+
+ /**
+ * Get the default network status filter of the template.
+ */
+ @NetworkStats.DefaultNetwork
+ public int getDefaultNetworkStatus() {
+ return mDefaultNetwork;
+ }
+
+ /**
+ * Get the Radio Access Technology(RAT) type filter of the template.
+ */
+ public int getRatType() {
+ return mSubType;
+ }
+
+ /**
+ * Get the OEM managed filter of the template. See {@code OEM_MANAGED_*} or
+ * {@code android.net.NetworkIdentity#OEM_*}.
+ */
+ @OemManaged
+ public int getOemManaged() {
+ return mOemManaged;
+ }
+
+ /**
* Test if given {@link NetworkIdentity} matches this template.
+ *
+ * @hide
*/
public boolean matches(NetworkIdentity ident) {
if (!matchesMetered(ident)) return false;
@@ -565,6 +726,8 @@
* Check if this template matches {@code subscriberId}. Returns true if this
* template was created with {@code SUBSCRIBER_ID_MATCH_RULE_ALL}, or with a
* {@code mMatchSubscriberIds} array that contains {@code subscriberId}.
+ *
+ * @hide
*/
public boolean matchesSubscriberId(@Nullable String subscriberId) {
return mSubscriberIdMatchRule == SUBSCRIBER_ID_MATCH_RULE_ALL
@@ -573,10 +736,10 @@
/**
* Check if network with matching SSID. Returns true when the SSID matches, or when
- * {@code mNetworkId} is {@code WIFI_NETWORKID_ALL}.
+ * {@code mNetworkId} is {@code WIFI_NETWORK_KEY_ALL}.
*/
private boolean matchesWifiNetworkId(@Nullable String networkId) {
- return Objects.equals(mNetworkId, WIFI_NETWORKID_ALL)
+ return Objects.equals(mNetworkId, WIFI_NETWORK_KEY_ALL)
|| Objects.equals(sanitizeSsid(mNetworkId), sanitizeSsid(networkId));
}
@@ -599,10 +762,13 @@
* The mapping is corresponding to {@code TelephonyManager#NETWORK_CLASS_BIT_MASK_*}.
*
* @param ratType An integer defined in {@code TelephonyManager#NETWORK_TYPE_*}.
+ *
+ * @hide
*/
// TODO: 1. Consider move this to TelephonyManager if used by other modules.
// 2. Consider make this configurable.
// 3. Use TelephonyManager APIs when available.
+ // TODO: @SystemApi when ready.
public static int getCollapsedRatType(int ratType) {
switch (ratType) {
case TelephonyManager.NETWORK_TYPE_GPRS:
@@ -639,7 +805,10 @@
/**
* Return all supported collapsed RAT types that could be returned by
* {@link #getCollapsedRatType(int)}.
+ *
+ * @hide
*/
+ // TODO: @SystemApi when ready.
@NonNull
public static final int[] getAllCollapsedRatTypes() {
final int[] ratTypes = TelephonyManager.getAllNetworkTypes();
@@ -779,6 +948,8 @@
* active merge set [A,B], we'd return a new template that primarily matches
* A, but also matches B.
* TODO: remove and use {@link #normalize(NetworkTemplate, List)}.
+ *
+ * @hide
*/
@UnsupportedAppUsage
public static NetworkTemplate normalize(NetworkTemplate template, String[] merged) {
@@ -797,7 +968,10 @@
* For example, given an incoming template matching B, and the currently
* active merge set [A,B], we'd return a new template that primarily matches
* A, but also matches B.
+ *
+ * @hide
*/
+ // TODO: @SystemApi when ready.
public static NetworkTemplate normalize(NetworkTemplate template, List<String[]> mergedList) {
// Now there are several types of network which uses SubscriberId to store network
// information. For instances:
@@ -830,4 +1004,184 @@
return new NetworkTemplate[size];
}
};
+
+ /**
+ * Builder class for NetworkTemplate.
+ */
+ public static final class Builder {
+ private final int mMatchRule;
+ // Use a SortedSet to provide a deterministic order when fetching the first one.
+ @NonNull
+ private final SortedSet<String> mMatchSubscriberIds = new TreeSet<>();
+ @Nullable
+ private String mWifiNetworkKey;
+
+ // Matches for the NetworkStats constants METERED_*, ROAMING_* and DEFAULT_NETWORK_*.
+ private int mMetered;
+ private int mRoaming;
+ private int mDefaultNetwork;
+ private int mRatType;
+
+ // Bitfield containing OEM network properties {@code NetworkIdentity#OEM_*}.
+ private int mOemManaged;
+
+ /**
+ * Creates a new Builder with given match rule to construct NetworkTemplate objects.
+ *
+ * @param matchRule the match rule of the template, see {@code MATCH_*}.
+ */
+ public Builder(@TemplateMatchRule final int matchRule) {
+ assertRequestableMatchRule(matchRule);
+ // Initialize members with default values.
+ mMatchRule = matchRule;
+ mWifiNetworkKey = WIFI_NETWORK_KEY_ALL;
+ mMetered = METERED_ALL;
+ mRoaming = ROAMING_ALL;
+ mDefaultNetwork = DEFAULT_NETWORK_ALL;
+ mRatType = NETWORK_TYPE_ALL;
+ mOemManaged = OEM_MANAGED_ALL;
+ }
+
+ /**
+ * Set the Subscriber Ids. Calling this function with an empty set represents
+ * the intention of matching any Subscriber Ids.
+ *
+ * @param subscriberIds the list of Subscriber Ids.
+ * @return this builder.
+ */
+ @NonNull
+ public Builder setSubscriberIds(@NonNull Set<String> subscriberIds) {
+ Objects.requireNonNull(subscriberIds);
+ mMatchSubscriberIds.clear();
+ mMatchSubscriberIds.addAll(subscriberIds);
+ return this;
+ }
+
+ /**
+ * Set the Wifi Network Key.
+ *
+ * @param wifiNetworkKey the Wifi Network Key, see {@link WifiInfo#getCurrentNetworkKey()}.
+ * Or null to match all networks.
+ * @return this builder.
+ */
+ @NonNull
+ public Builder setWifiNetworkKey(@Nullable String wifiNetworkKey) {
+ mWifiNetworkKey = wifiNetworkKey;
+ return this;
+ }
+
+ /**
+ * Set the meteredness filter.
+ *
+ * @param metered the meteredness filter.
+ * @return this builder.
+ */
+ @NonNull
+ public Builder setMeteredness(@NetworkStats.Meteredness int metered) {
+ mMetered = metered;
+ return this;
+ }
+
+ /**
+ * Set the roaming filter.
+ *
+ * @param roaming the roaming filter.
+ * @return this builder.
+ */
+ @NonNull
+ public Builder setRoaming(@NetworkStats.Roaming int roaming) {
+ mRoaming = roaming;
+ return this;
+ }
+
+ /**
+ * Set the default network status filter.
+ *
+ * @param defaultNetwork the default network status filter.
+ * @return this builder.
+ */
+ @NonNull
+ public Builder setDefaultNetworkStatus(@NetworkStats.DefaultNetwork int defaultNetwork) {
+ mDefaultNetwork = defaultNetwork;
+ return this;
+ }
+
+ /**
+ * Set the Radio Access Technology(RAT) type filter.
+ *
+ * @param ratType the Radio Access Technology(RAT) type filter. Use
+ * {@link #NETWORK_TYPE_ALL} to include all network types when filtering.
+ * See {@code TelephonyManager.NETWORK_TYPE_*}.
+ * @return this builder.
+ */
+ @NonNull
+ public Builder setRatType(@NetworkType int ratType) {
+ // Input will be validated with the match rule when building the template.
+ mRatType = ratType;
+ return this;
+ }
+
+ /**
+ * Set the OEM managed filter.
+ *
+ * @param oemManaged the match rule to match different type of OEM managed network or
+ * unmanaged networks. See {@code OEM_MANAGED_*}.
+ * @return this builder.
+ */
+ @NonNull
+ public Builder setOemManaged(@OemManaged int oemManaged) {
+ mOemManaged = oemManaged;
+ return this;
+ }
+
+ /**
+ * Check whether the match rule is requestable.
+ *
+ * @param matchRule the target match rule to be checked.
+ */
+ private static void assertRequestableMatchRule(final int matchRule) {
+ if (!isKnownMatchRule(matchRule)
+ || matchRule == MATCH_PROXY
+ || matchRule == MATCH_MOBILE_WILDCARD
+ || matchRule == MATCH_WIFI_WILDCARD) {
+ throw new IllegalArgumentException("Invalid match rule: "
+ + getMatchRuleName(matchRule));
+ }
+ }
+
+ private void assertRequestableParameters() {
+ // TODO: Check all the input are legitimate.
+ }
+
+ /**
+ * For backward compatibility, deduce match rule to a wildcard match rule
+ * if the Subscriber Ids are empty.
+ */
+ private int getWildcardDeducedMatchRule() {
+ if (mMatchRule == MATCH_MOBILE && mMatchSubscriberIds.isEmpty()) {
+ return MATCH_MOBILE_WILDCARD;
+ } else if (mMatchRule == MATCH_WIFI && mMatchSubscriberIds.isEmpty()
+ && mWifiNetworkKey == WIFI_NETWORK_KEY_ALL) {
+ return MATCH_WIFI_WILDCARD;
+ }
+ return mMatchRule;
+ }
+
+ /**
+ * Builds the instance of the NetworkTemplate.
+ *
+ * @return the built instance of NetworkTemplate.
+ */
+ @NonNull
+ public NetworkTemplate build() {
+ assertRequestableParameters();
+ final int subscriberIdMatchRule = mMatchSubscriberIds.isEmpty()
+ ? SUBSCRIBER_ID_MATCH_RULE_ALL : SUBSCRIBER_ID_MATCH_RULE_EXACT;
+ return new NetworkTemplate(getWildcardDeducedMatchRule(),
+ mMatchSubscriberIds.isEmpty() ? null : mMatchSubscriberIds.iterator().next(),
+ mMatchSubscriberIds.toArray(new String[0]),
+ mWifiNetworkKey, mMetered, mRoaming, mDefaultNetwork, mRatType, mOemManaged,
+ subscriberIdMatchRule);
+ }
+ }
}