Merge "API review: SubscriptionPlan#getNetworkTypes/setNetworkTypes"
diff --git a/api/current.txt b/api/current.txt
index 4bb1f70..770be33 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -45872,7 +45872,7 @@
method public long getDataLimitBytes();
method public long getDataUsageBytes();
method public long getDataUsageTime();
- method @Nullable public int[] getNetworkTypes();
+ method @NonNull public int[] getNetworkTypes();
method @Nullable public CharSequence getSummary();
method @Nullable public CharSequence getTitle();
method public void writeToParcel(android.os.Parcel, int);
@@ -45892,7 +45892,7 @@
method public static android.telephony.SubscriptionPlan.Builder createRecurring(java.time.ZonedDateTime, java.time.Period);
method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int);
method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long);
- method @NonNull public android.telephony.SubscriptionPlan.Builder setNetworkTypes(@Nullable int[]);
+ method @NonNull public android.telephony.SubscriptionPlan.Builder setNetworkTypes(@NonNull int[]);
method public android.telephony.SubscriptionPlan.Builder setSummary(@Nullable CharSequence);
method public android.telephony.SubscriptionPlan.Builder setTitle(@Nullable CharSequence);
}
diff --git a/core/java/android/telephony/SubscriptionPlan.java b/core/java/android/telephony/SubscriptionPlan.java
index ff2f4ad..901957f 100644
--- a/core/java/android/telephony/SubscriptionPlan.java
+++ b/core/java/android/telephony/SubscriptionPlan.java
@@ -91,10 +91,11 @@
private long dataUsageBytes = BYTES_UNKNOWN;
private long dataUsageTime = TIME_UNKNOWN;
private @NetworkType int[] networkTypes;
- private long networkTypesBitMask;
private SubscriptionPlan(RecurrenceRule cycleRule) {
this.cycleRule = Preconditions.checkNotNull(cycleRule);
+ this.networkTypes = Arrays.copyOf(TelephonyManager.getAllNetworkTypes(),
+ TelephonyManager.getAllNetworkTypes().length);
}
private SubscriptionPlan(Parcel source) {
@@ -221,10 +222,10 @@
/**
* Return an array containing all {@link NetworkType}s this SubscriptionPlan applies to.
- * A null value means this SubscriptionPlan applies to all network types.
+ * @see TelephonyManager for network types values
*/
- public @Nullable @NetworkType int[] getNetworkTypes() {
- return networkTypes;
+ public @NonNull @NetworkType int[] getNetworkTypes() {
+ return Arrays.copyOf(networkTypes, networkTypes.length);
}
/**
@@ -361,14 +362,14 @@
}
/**
- * Set the network types this SubscriptionPlan applies to.
+ * Set the network types this SubscriptionPlan applies to. By default the plan will apply
+ * to all network types. An empty array means this plan applies to no network types.
*
- * @param networkTypes a set of all {@link NetworkType}s that apply to this plan.
- * A null value means the plan applies to all network types,
- * and an empty array means the plan applies to no network types.
+ * @param networkTypes an array of all {@link NetworkType}s that apply to this plan.
+ * @see TelephonyManager for network type values
*/
- public @NonNull Builder setNetworkTypes(@Nullable @NetworkType int[] networkTypes) {
- plan.networkTypes = networkTypes;
+ public @NonNull Builder setNetworkTypes(@NonNull @NetworkType int[] networkTypes) {
+ plan.networkTypes = Arrays.copyOf(networkTypes, networkTypes.length);
return this;
}
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 99f3d8f..22ed661 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -3091,17 +3091,38 @@
private void enforceSubscriptionPlanValidity(SubscriptionPlan[] plans) {
// nothing to check if no plans
if (plans.length == 0) {
+ Log.d(TAG, "Received empty plans list. Clearing existing SubscriptionPlans.");
return;
}
- final ArraySet<Integer> applicableNetworkTypes = new ArraySet<Integer>();
- boolean allNetworks = false;
- for (SubscriptionPlan plan : plans) {
- if (plan.getNetworkTypes() == null) {
- allNetworks = true;
+ final int[] allNetworkTypes = TelephonyManager.getAllNetworkTypes();
+ final ArraySet<Integer> allNetworksSet = new ArraySet<>();
+ addAll(allNetworksSet, allNetworkTypes);
+
+ final ArraySet<Integer> applicableNetworkTypes = new ArraySet<>();
+ boolean hasGeneralPlan = false;
+ for (int i = 0; i < plans.length; i++) {
+ final int[] planNetworkTypes = plans[i].getNetworkTypes();
+ final ArraySet<Integer> planNetworksSet = new ArraySet<>();
+ for (int j = 0; j < planNetworkTypes.length; j++) {
+ // ensure all network types are valid
+ if (allNetworksSet.contains(planNetworkTypes[j])) {
+ // ensure no duplicate network types in the same SubscriptionPlan
+ if (!planNetworksSet.add(planNetworkTypes[j])) {
+ throw new IllegalArgumentException(
+ "Subscription plan contains duplicate network types.");
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid network type: "
+ + planNetworkTypes[j]);
+ }
+ }
+
+ if (planNetworkTypes.length == allNetworkTypes.length) {
+ hasGeneralPlan = true;
} else {
- final int[] networkTypes = plan.getNetworkTypes();
- if (!addAll(applicableNetworkTypes, networkTypes)) {
+ // ensure no network type applies to multiple plans
+ if (!addAll(applicableNetworkTypes, planNetworkTypes)) {
throw new IllegalArgumentException(
"Multiple subscription plans defined for a single network type.");
}
@@ -3109,7 +3130,7 @@
}
// ensure at least one plan applies for every network type
- if (!allNetworks) {
+ if (!hasGeneralPlan) {
throw new IllegalArgumentException(
"No generic subscription plan that applies to all network types.");
}
@@ -3118,12 +3139,12 @@
/**
* Adds all of the {@code elements} to the {@code set}.
*
- * @return {@code false} if any element is not added because the set already have the value.
+ * @return {@code false} if any element is not added because the set already has the value.
*/
- private static boolean addAll(@NonNull Set<Integer> set, @NonNull int... elements) {
+ private static boolean addAll(@NonNull ArraySet<Integer> set, @NonNull int... elements) {
boolean result = true;
- for (int element : elements) {
- result &= set.add(element);
+ for (int i = 0; i < elements.length; i++) {
+ result &= set.add(elements[i]);
}
return result;
}