Loading api/current.txt +2 −2 Original line number Original line Diff line number Diff line Loading @@ -48110,7 +48110,7 @@ package android.telephony { method public long getDataLimitBytes(); method public long getDataLimitBytes(); method public long getDataUsageBytes(); method public long getDataUsageBytes(); method public long getDataUsageTime(); method public long getDataUsageTime(); method @Nullable public int[] getNetworkTypes(); method @NonNull public int[] getNetworkTypes(); method @Nullable public CharSequence getSummary(); method @Nullable public CharSequence getSummary(); method @Nullable public CharSequence getTitle(); method @Nullable public CharSequence getTitle(); method public void writeToParcel(android.os.Parcel, int); method public void writeToParcel(android.os.Parcel, int); Loading @@ -48130,7 +48130,7 @@ package android.telephony { method public static android.telephony.SubscriptionPlan.Builder createRecurring(java.time.ZonedDateTime, java.time.Period); 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 setDataLimit(long, int); method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long); 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 setSummary(@Nullable CharSequence); method public android.telephony.SubscriptionPlan.Builder setTitle(@Nullable CharSequence); method public android.telephony.SubscriptionPlan.Builder setTitle(@Nullable CharSequence); } } core/java/android/telephony/SubscriptionPlan.java +11 −10 Original line number Original line Diff line number Diff line Loading @@ -91,10 +91,11 @@ public final class SubscriptionPlan implements Parcelable { private long dataUsageBytes = BYTES_UNKNOWN; private long dataUsageBytes = BYTES_UNKNOWN; private long dataUsageTime = TIME_UNKNOWN; private long dataUsageTime = TIME_UNKNOWN; private @NetworkType int[] networkTypes; private @NetworkType int[] networkTypes; private long networkTypesBitMask; private SubscriptionPlan(RecurrenceRule cycleRule) { private SubscriptionPlan(RecurrenceRule cycleRule) { this.cycleRule = Preconditions.checkNotNull(cycleRule); this.cycleRule = Preconditions.checkNotNull(cycleRule); this.networkTypes = Arrays.copyOf(TelephonyManager.getAllNetworkTypes(), TelephonyManager.getAllNetworkTypes().length); } } private SubscriptionPlan(Parcel source) { private SubscriptionPlan(Parcel source) { Loading Loading @@ -221,10 +222,10 @@ public final class SubscriptionPlan implements Parcelable { /** /** * Return an array containing all {@link NetworkType}s this SubscriptionPlan applies to. * 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() { public @NonNull @NetworkType int[] getNetworkTypes() { return networkTypes; return Arrays.copyOf(networkTypes, networkTypes.length); } } /** /** Loading Loading @@ -361,14 +362,14 @@ public final class SubscriptionPlan implements Parcelable { } } /** /** * 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. * @param networkTypes an array of all {@link NetworkType}s that apply to this plan. * A null value means the plan applies to all network types, * @see TelephonyManager for network type values * and an empty array means the plan applies to no network types. */ */ public @NonNull Builder setNetworkTypes(@Nullable @NetworkType int[] networkTypes) { public @NonNull Builder setNetworkTypes(@NonNull @NetworkType int[] networkTypes) { plan.networkTypes = networkTypes; plan.networkTypes = Arrays.copyOf(networkTypes, networkTypes.length); return this; return this; } } } } Loading services/core/java/com/android/server/net/NetworkPolicyManagerService.java +33 −12 Original line number Original line Diff line number Diff line Loading @@ -3087,17 +3087,38 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private void enforceSubscriptionPlanValidity(SubscriptionPlan[] plans) { private void enforceSubscriptionPlanValidity(SubscriptionPlan[] plans) { // nothing to check if no plans // nothing to check if no plans if (plans.length == 0) { if (plans.length == 0) { Log.d(TAG, "Received empty plans list. Clearing existing SubscriptionPlans."); return; return; } } final ArraySet<Integer> applicableNetworkTypes = new ArraySet<Integer>(); final int[] allNetworkTypes = TelephonyManager.getAllNetworkTypes(); boolean allNetworks = false; final ArraySet<Integer> allNetworksSet = new ArraySet<>(); for (SubscriptionPlan plan : plans) { addAll(allNetworksSet, allNetworkTypes); if (plan.getNetworkTypes() == null) { allNetworks = true; 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 { } else { final int[] networkTypes = plan.getNetworkTypes(); // ensure no network type applies to multiple plans if (!addAll(applicableNetworkTypes, networkTypes)) { if (!addAll(applicableNetworkTypes, planNetworkTypes)) { throw new IllegalArgumentException( throw new IllegalArgumentException( "Multiple subscription plans defined for a single network type."); "Multiple subscription plans defined for a single network type."); } } Loading @@ -3105,7 +3126,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } // ensure at least one plan applies for every network type // ensure at least one plan applies for every network type if (!allNetworks) { if (!hasGeneralPlan) { throw new IllegalArgumentException( throw new IllegalArgumentException( "No generic subscription plan that applies to all network types."); "No generic subscription plan that applies to all network types."); } } Loading @@ -3114,12 +3135,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { /** /** * Adds all of the {@code elements} to the {@code set}. * 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; boolean result = true; for (int element : elements) { for (int i = 0; i < elements.length; i++) { result &= set.add(element); result &= set.add(elements[i]); } } return result; return result; } } Loading Loading
api/current.txt +2 −2 Original line number Original line Diff line number Diff line Loading @@ -48110,7 +48110,7 @@ package android.telephony { method public long getDataLimitBytes(); method public long getDataLimitBytes(); method public long getDataUsageBytes(); method public long getDataUsageBytes(); method public long getDataUsageTime(); method public long getDataUsageTime(); method @Nullable public int[] getNetworkTypes(); method @NonNull public int[] getNetworkTypes(); method @Nullable public CharSequence getSummary(); method @Nullable public CharSequence getSummary(); method @Nullable public CharSequence getTitle(); method @Nullable public CharSequence getTitle(); method public void writeToParcel(android.os.Parcel, int); method public void writeToParcel(android.os.Parcel, int); Loading @@ -48130,7 +48130,7 @@ package android.telephony { method public static android.telephony.SubscriptionPlan.Builder createRecurring(java.time.ZonedDateTime, java.time.Period); 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 setDataLimit(long, int); method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long); 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 setSummary(@Nullable CharSequence); method public android.telephony.SubscriptionPlan.Builder setTitle(@Nullable CharSequence); method public android.telephony.SubscriptionPlan.Builder setTitle(@Nullable CharSequence); } }
core/java/android/telephony/SubscriptionPlan.java +11 −10 Original line number Original line Diff line number Diff line Loading @@ -91,10 +91,11 @@ public final class SubscriptionPlan implements Parcelable { private long dataUsageBytes = BYTES_UNKNOWN; private long dataUsageBytes = BYTES_UNKNOWN; private long dataUsageTime = TIME_UNKNOWN; private long dataUsageTime = TIME_UNKNOWN; private @NetworkType int[] networkTypes; private @NetworkType int[] networkTypes; private long networkTypesBitMask; private SubscriptionPlan(RecurrenceRule cycleRule) { private SubscriptionPlan(RecurrenceRule cycleRule) { this.cycleRule = Preconditions.checkNotNull(cycleRule); this.cycleRule = Preconditions.checkNotNull(cycleRule); this.networkTypes = Arrays.copyOf(TelephonyManager.getAllNetworkTypes(), TelephonyManager.getAllNetworkTypes().length); } } private SubscriptionPlan(Parcel source) { private SubscriptionPlan(Parcel source) { Loading Loading @@ -221,10 +222,10 @@ public final class SubscriptionPlan implements Parcelable { /** /** * Return an array containing all {@link NetworkType}s this SubscriptionPlan applies to. * 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() { public @NonNull @NetworkType int[] getNetworkTypes() { return networkTypes; return Arrays.copyOf(networkTypes, networkTypes.length); } } /** /** Loading Loading @@ -361,14 +362,14 @@ public final class SubscriptionPlan implements Parcelable { } } /** /** * 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. * @param networkTypes an array of all {@link NetworkType}s that apply to this plan. * A null value means the plan applies to all network types, * @see TelephonyManager for network type values * and an empty array means the plan applies to no network types. */ */ public @NonNull Builder setNetworkTypes(@Nullable @NetworkType int[] networkTypes) { public @NonNull Builder setNetworkTypes(@NonNull @NetworkType int[] networkTypes) { plan.networkTypes = networkTypes; plan.networkTypes = Arrays.copyOf(networkTypes, networkTypes.length); return this; return this; } } } } Loading
services/core/java/com/android/server/net/NetworkPolicyManagerService.java +33 −12 Original line number Original line Diff line number Diff line Loading @@ -3087,17 +3087,38 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private void enforceSubscriptionPlanValidity(SubscriptionPlan[] plans) { private void enforceSubscriptionPlanValidity(SubscriptionPlan[] plans) { // nothing to check if no plans // nothing to check if no plans if (plans.length == 0) { if (plans.length == 0) { Log.d(TAG, "Received empty plans list. Clearing existing SubscriptionPlans."); return; return; } } final ArraySet<Integer> applicableNetworkTypes = new ArraySet<Integer>(); final int[] allNetworkTypes = TelephonyManager.getAllNetworkTypes(); boolean allNetworks = false; final ArraySet<Integer> allNetworksSet = new ArraySet<>(); for (SubscriptionPlan plan : plans) { addAll(allNetworksSet, allNetworkTypes); if (plan.getNetworkTypes() == null) { allNetworks = true; 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 { } else { final int[] networkTypes = plan.getNetworkTypes(); // ensure no network type applies to multiple plans if (!addAll(applicableNetworkTypes, networkTypes)) { if (!addAll(applicableNetworkTypes, planNetworkTypes)) { throw new IllegalArgumentException( throw new IllegalArgumentException( "Multiple subscription plans defined for a single network type."); "Multiple subscription plans defined for a single network type."); } } Loading @@ -3105,7 +3126,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } // ensure at least one plan applies for every network type // ensure at least one plan applies for every network type if (!allNetworks) { if (!hasGeneralPlan) { throw new IllegalArgumentException( throw new IllegalArgumentException( "No generic subscription plan that applies to all network types."); "No generic subscription plan that applies to all network types."); } } Loading @@ -3114,12 +3135,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { /** /** * Adds all of the {@code elements} to the {@code set}. * 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; boolean result = true; for (int element : elements) { for (int i = 0; i < elements.length; i++) { result &= set.add(element); result &= set.add(elements[i]); } } return result; return result; } } Loading