Merge "carrier data usage: Use carrier template as default policy"

This commit is contained in:
Les Lee
2021-06-01 10:42:08 +00:00
committed by Gerrit Code Review
5 changed files with 163 additions and 70 deletions

View File

@@ -514,6 +514,10 @@ public class NetworkTemplate implements Parcelable {
return mSubscriberIdMatchRule; return mSubscriberIdMatchRule;
} }
public int getMeteredness() {
return mMetered;
}
/** /**
* Test if given {@link NetworkIdentity} matches this template. * Test if given {@link NetworkIdentity} matches this template.
*/ */

View File

@@ -97,8 +97,12 @@ import static android.net.NetworkPolicyManager.resolveNetworkId;
import static android.net.NetworkPolicyManager.uidPoliciesToString; import static android.net.NetworkPolicyManager.uidPoliciesToString;
import static android.net.NetworkPolicyManager.uidRulesToString; import static android.net.NetworkPolicyManager.uidRulesToString;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.net.NetworkStats.METERED_ALL;
import static android.net.NetworkStats.METERED_YES;
import static android.net.NetworkTemplate.MATCH_CARRIER;
import static android.net.NetworkTemplate.MATCH_MOBILE; import static android.net.NetworkTemplate.MATCH_MOBILE;
import static android.net.NetworkTemplate.MATCH_WIFI; import static android.net.NetworkTemplate.MATCH_WIFI;
import static android.net.NetworkTemplate.buildTemplateCarrierMetered;
import static android.net.NetworkTemplate.buildTemplateMobileAll; import static android.net.NetworkTemplate.buildTemplateMobileAll;
import static android.net.TrafficStats.MB_IN_BYTES; import static android.net.TrafficStats.MB_IN_BYTES;
import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED; import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
@@ -350,7 +354,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private static final int VERSION_SWITCH_UID = 10; private static final int VERSION_SWITCH_UID = 10;
private static final int VERSION_ADDED_CYCLE = 11; private static final int VERSION_ADDED_CYCLE = 11;
private static final int VERSION_ADDED_NETWORK_TYPES = 12; private static final int VERSION_ADDED_NETWORK_TYPES = 12;
private static final int VERSION_LATEST = VERSION_ADDED_NETWORK_TYPES; private static final int VERSION_SUPPORTED_CARRIER_USAGE = 13;
private static final int VERSION_LATEST = VERSION_SUPPORTED_CARRIER_USAGE;
@VisibleForTesting @VisibleForTesting
public static final int TYPE_WARNING = SystemMessage.NOTE_NET_WARNING; public static final int TYPE_WARNING = SystemMessage.NOTE_NET_WARNING;
@@ -375,7 +380,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground"; private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground";
private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate"; private static final String ATTR_NETWORK_TEMPLATE = "networkTemplate";
private static final String ATTR_SUBSCRIBER_ID = "subscriberId"; private static final String ATTR_SUBSCRIBER_ID = "subscriberId";
private static final String ATTR_SUBSCRIBER_ID_MATCH_RULE = "subscriberIdMatchRule";
private static final String ATTR_NETWORK_ID = "networkId"; private static final String ATTR_NETWORK_ID = "networkId";
private static final String ATTR_TEMPLATE_METERED = "templateMetered";
@Deprecated private static final String ATTR_CYCLE_DAY = "cycleDay"; @Deprecated private static final String ATTR_CYCLE_DAY = "cycleDay";
@Deprecated private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone"; @Deprecated private static final String ATTR_CYCLE_TIMEZONE = "cycleTimezone";
private static final String ATTR_CYCLE_START = "cycleStart"; private static final String ATTR_CYCLE_START = "cycleStart";
@@ -1430,7 +1437,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
*/ */
@GuardedBy("mNetworkPoliciesSecondLock") @GuardedBy("mNetworkPoliciesSecondLock")
private int findRelevantSubIdNL(NetworkTemplate template) { private int findRelevantSubIdNL(NetworkTemplate template) {
// Mobile template is relevant when any active subscriber matches // Carrier template is relevant when any active subscriber matches
for (int i = 0; i < mSubIdToSubscriberId.size(); i++) { for (int i = 0; i < mSubIdToSubscriberId.size(); i++) {
final int subId = mSubIdToSubscriberId.keyAt(i); final int subId = mSubIdToSubscriberId.keyAt(i);
final String subscriberId = mSubIdToSubscriberId.valueAt(i); final String subscriberId = mSubIdToSubscriberId.valueAt(i);
@@ -1508,6 +1515,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} }
case TYPE_LIMIT: { case TYPE_LIMIT: {
switch (policy.template.getMatchRule()) { switch (policy.template.getMatchRule()) {
case MATCH_CARRIER:
case MATCH_MOBILE: case MATCH_MOBILE:
title = res.getText(R.string.data_usage_mobile_limit_title); title = res.getText(R.string.data_usage_mobile_limit_title);
break; break;
@@ -1536,6 +1544,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} }
case TYPE_LIMIT_SNOOZED: { case TYPE_LIMIT_SNOOZED: {
switch (policy.template.getMatchRule()) { switch (policy.template.getMatchRule()) {
case MATCH_CARRIER:
case MATCH_MOBILE: case MATCH_MOBILE:
title = res.getText(R.string.data_usage_mobile_limit_snoozed_title); title = res.getText(R.string.data_usage_mobile_limit_snoozed_title);
break; break;
@@ -1632,7 +1641,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
synchronized (mUidRulesFirstLock) { synchronized (mUidRulesFirstLock) {
synchronized (mNetworkPoliciesSecondLock) { synchronized (mNetworkPoliciesSecondLock) {
ensureActiveMobilePolicyAL(); ensureActiveCarrierPolicyAL();
normalizePoliciesNL(); normalizePoliciesNL();
updateNetworkEnabledNL(); updateNetworkEnabledNL();
updateNetworkRulesNL(); updateNetworkRulesNL();
@@ -1657,17 +1666,17 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} }
/** /**
* Update mobile policies with data cycle information from {@link CarrierConfigManager} * Update carrier policies with data cycle information from {@link CarrierConfigManager}
* if necessary. * if necessary.
* *
* @param subId that has its associated NetworkPolicy updated if necessary * @param subId that has its associated NetworkPolicy updated if necessary
* @return if any policies were updated * @return if any policies were updated
*/ */
@GuardedBy("mNetworkPoliciesSecondLock") @GuardedBy("mNetworkPoliciesSecondLock")
private boolean maybeUpdateMobilePolicyCycleAL(int subId, String subscriberId) { private boolean maybeUpdateCarrierPolicyCycleAL(int subId, String subscriberId) {
if (LOGV) Slog.v(TAG, "maybeUpdateMobilePolicyCycleAL()"); if (LOGV) Slog.v(TAG, "maybeUpdateCarrierPolicyCycleAL()");
// find and update the mobile NetworkPolicy for this subscriber id // find and update the carrier NetworkPolicy for this subscriber id
boolean policyUpdated = false; boolean policyUpdated = false;
final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true, TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true,
@@ -1676,21 +1685,21 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final NetworkTemplate template = mNetworkPolicy.keyAt(i); final NetworkTemplate template = mNetworkPolicy.keyAt(i);
if (template.matches(probeIdent)) { if (template.matches(probeIdent)) {
final NetworkPolicy policy = mNetworkPolicy.valueAt(i); final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
policyUpdated |= updateDefaultMobilePolicyAL(subId, policy); policyUpdated |= updateDefaultCarrierPolicyAL(subId, policy);
} }
} }
return policyUpdated; return policyUpdated;
} }
/** /**
* Returns the cycle day that should be used for a mobile NetworkPolicy. * Returns the cycle day that should be used for a carrier NetworkPolicy.
* *
* It attempts to get an appropriate cycle day from the passed in CarrierConfig. If it's unable * It attempts to get an appropriate cycle day from the passed in CarrierConfig. If it's unable
* to do so, it returns the fallback value. * to do so, it returns the fallback value.
* *
* @param config The CarrierConfig to read the value from. * @param config The CarrierConfig to read the value from.
* @param fallbackCycleDay to return if the CarrierConfig can't be read. * @param fallbackCycleDay to return if the CarrierConfig can't be read.
* @return cycleDay to use in the mobile NetworkPolicy. * @return cycleDay to use in the carrier NetworkPolicy.
*/ */
@VisibleForTesting @VisibleForTesting
int getCycleDayFromCarrierConfig(@Nullable PersistableBundle config, int getCycleDayFromCarrierConfig(@Nullable PersistableBundle config,
@@ -1715,14 +1724,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} }
/** /**
* Returns the warning bytes that should be used for a mobile NetworkPolicy. * Returns the warning bytes that should be used for a carrier NetworkPolicy.
* *
* It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable * It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable
* to do so, it returns the fallback value. * to do so, it returns the fallback value.
* *
* @param config The CarrierConfig to read the value from. * @param config The CarrierConfig to read the value from.
* @param fallbackWarningBytes to return if the CarrierConfig can't be read. * @param fallbackWarningBytes to return if the CarrierConfig can't be read.
* @return warningBytes to use in the mobile NetworkPolicy. * @return warningBytes to use in the carrier NetworkPolicy.
*/ */
@VisibleForTesting @VisibleForTesting
long getWarningBytesFromCarrierConfig(@Nullable PersistableBundle config, long getWarningBytesFromCarrierConfig(@Nullable PersistableBundle config,
@@ -1748,14 +1757,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} }
/** /**
* Returns the limit bytes that should be used for a mobile NetworkPolicy. * Returns the limit bytes that should be used for a carrier NetworkPolicy.
* *
* It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable * It attempts to get an appropriate value from the passed in CarrierConfig. If it's unable
* to do so, it returns the fallback value. * to do so, it returns the fallback value.
* *
* @param config The CarrierConfig to read the value from. * @param config The CarrierConfig to read the value from.
* @param fallbackLimitBytes to return if the CarrierConfig can't be read. * @param fallbackLimitBytes to return if the CarrierConfig can't be read.
* @return limitBytes to use in the mobile NetworkPolicy. * @return limitBytes to use in the carrier NetworkPolicy.
*/ */
@VisibleForTesting @VisibleForTesting
long getLimitBytesFromCarrierConfig(@Nullable PersistableBundle config, long getLimitBytesFromCarrierConfig(@Nullable PersistableBundle config,
@@ -1801,8 +1810,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
synchronized (mNetworkPoliciesSecondLock) { synchronized (mNetworkPoliciesSecondLock) {
final String subscriberId = mSubIdToSubscriberId.get(subId, null); final String subscriberId = mSubIdToSubscriberId.get(subId, null);
if (subscriberId != null) { if (subscriberId != null) {
ensureActiveMobilePolicyAL(subId, subscriberId); ensureActiveCarrierPolicyAL(subId, subscriberId);
maybeUpdateMobilePolicyCycleAL(subId, subscriberId); maybeUpdateCarrierPolicyCycleAL(subId, subscriberId);
} else { } else {
Slog.wtf(TAG, "Missing subscriberId for subId " + subId); Slog.wtf(TAG, "Missing subscriberId for subId " + subId);
} }
@@ -1888,10 +1897,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// TODO: reach into ConnectivityManager to proactively disable bringing // TODO: reach into ConnectivityManager to proactively disable bringing
// up this network, since we know that traffic will be blocked. // up this network, since we know that traffic will be blocked.
if (template.getMatchRule() == MATCH_MOBILE) { if (template.getMatchRule() == MATCH_MOBILE
// If mobile data usage hits the limit or if the user resumes the data, we need to || template.getMatchRule() == MATCH_CARRIER) {
// If carrier data usage hits the limit or if the user resumes the data, we need to
// notify telephony. // notify telephony.
// TODO: It needs to check if it matches the merged WIFI and notify to wifi module.
final IntArray matchingSubIds = new IntArray(); final IntArray matchingSubIds = new IntArray();
synchronized (mNetworkPoliciesSecondLock) { synchronized (mNetworkPoliciesSecondLock) {
for (int i = 0; i < mSubIdToSubscriberId.size(); i++) { for (int i = 0; i < mSubIdToSubscriberId.size(); i++) {
@@ -2151,7 +2162,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
.truncatedTo(ChronoUnit.DAYS) .truncatedTo(ChronoUnit.DAYS)
.toInstant().toEpochMilli(); .toInstant().toEpochMilli();
final long totalBytes = getTotalBytes( final long totalBytes = getTotalBytes(
NetworkTemplate.buildTemplateMobileAll(snapshot.getSubscriberId()), buildTemplateCarrierMetered(snapshot.getSubscriberId()),
start, startOfDay); start, startOfDay);
final long remainingBytes = limitBytes - totalBytes; final long remainingBytes = limitBytes - totalBytes;
// Number of remaining days including current day // Number of remaining days including current day
@@ -2177,31 +2188,31 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
/** /**
* Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
* have at least a default mobile policy defined. * have at least a default carrier policy defined.
*/ */
@GuardedBy("mNetworkPoliciesSecondLock") @GuardedBy("mNetworkPoliciesSecondLock")
private void ensureActiveMobilePolicyAL() { private void ensureActiveCarrierPolicyAL() {
if (LOGV) Slog.v(TAG, "ensureActiveMobilePolicyAL()"); if (LOGV) Slog.v(TAG, "ensureActiveCarrierPolicyAL()");
if (mSuppressDefaultPolicy) return; if (mSuppressDefaultPolicy) return;
for (int i = 0; i < mSubIdToSubscriberId.size(); i++) { for (int i = 0; i < mSubIdToSubscriberId.size(); i++) {
final int subId = mSubIdToSubscriberId.keyAt(i); final int subId = mSubIdToSubscriberId.keyAt(i);
final String subscriberId = mSubIdToSubscriberId.valueAt(i); final String subscriberId = mSubIdToSubscriberId.valueAt(i);
ensureActiveMobilePolicyAL(subId, subscriberId); ensureActiveCarrierPolicyAL(subId, subscriberId);
} }
} }
/** /**
* Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
* have at least a default mobile policy defined. * have at least a default carrier policy defined.
* *
* @param subId to build a default policy for * @param subId to build a default policy for
* @param subscriberId that we check for an existing policy * @param subscriberId that we check for an existing policy
* @return true if a mobile network policy was added, or false one already existed. * @return true if a carrier network policy was added, or false one already existed.
*/ */
@GuardedBy("mNetworkPoliciesSecondLock") @GuardedBy("mNetworkPoliciesSecondLock")
private boolean ensureActiveMobilePolicyAL(int subId, String subscriberId) { private boolean ensureActiveCarrierPolicyAL(int subId, String subscriberId) {
// Poke around to see if we already have a policy // Poke around to see if we already have a policy
final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true, TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true,
@@ -2220,7 +2231,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
Slog.i(TAG, "No policy for subscriber " Slog.i(TAG, "No policy for subscriber "
+ NetworkIdentityUtils.scrubSubscriberId(subscriberId) + NetworkIdentityUtils.scrubSubscriberId(subscriberId)
+ "; generating default policy"); + "; generating default policy");
final NetworkPolicy policy = buildDefaultMobilePolicy(subId, subscriberId); final NetworkPolicy policy = buildDefaultCarrierPolicy(subId, subscriberId);
addNetworkPolicyAL(policy); addNetworkPolicyAL(policy);
return true; return true;
} }
@@ -2240,8 +2251,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} }
@VisibleForTesting @VisibleForTesting
NetworkPolicy buildDefaultMobilePolicy(int subId, String subscriberId) { NetworkPolicy buildDefaultCarrierPolicy(int subId, String subscriberId) {
final NetworkTemplate template = buildTemplateMobileAll(subscriberId); final NetworkTemplate template = buildTemplateCarrierMetered(subscriberId);
final RecurrenceRule cycleRule = NetworkPolicy final RecurrenceRule cycleRule = NetworkPolicy
.buildRule(ZonedDateTime.now().getDayOfMonth(), ZoneId.systemDefault()); .buildRule(ZonedDateTime.now().getDayOfMonth(), ZoneId.systemDefault());
final NetworkPolicy policy = new NetworkPolicy(template, cycleRule, final NetworkPolicy policy = new NetworkPolicy(template, cycleRule,
@@ -2249,7 +2260,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
SNOOZE_NEVER, SNOOZE_NEVER, true, true); SNOOZE_NEVER, SNOOZE_NEVER, true, true);
synchronized (mUidRulesFirstLock) { synchronized (mUidRulesFirstLock) {
synchronized (mNetworkPoliciesSecondLock) { synchronized (mNetworkPoliciesSecondLock) {
updateDefaultMobilePolicyAL(subId, policy); updateDefaultCarrierPolicyAL(subId, policy);
} }
} }
return policy; return policy;
@@ -2263,7 +2274,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
* @return if the policy was modified * @return if the policy was modified
*/ */
@GuardedBy("mNetworkPoliciesSecondLock") @GuardedBy("mNetworkPoliciesSecondLock")
private boolean updateDefaultMobilePolicyAL(int subId, NetworkPolicy policy) { private boolean updateDefaultCarrierPolicyAL(int subId, NetworkPolicy policy) {
if (!policy.inferred) { if (!policy.inferred) {
if (LOGD) Slog.d(TAG, "Ignoring user-defined policy " + policy); if (LOGD) Slog.d(TAG, "Ignoring user-defined policy " + policy);
return false; return false;
@@ -2350,14 +2361,33 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mLoadedRestrictBackground = (version >= VERSION_ADDED_RESTRICT_BACKGROUND) mLoadedRestrictBackground = (version >= VERSION_ADDED_RESTRICT_BACKGROUND)
&& readBooleanAttribute(in, ATTR_RESTRICT_BACKGROUND); && readBooleanAttribute(in, ATTR_RESTRICT_BACKGROUND);
} else if (TAG_NETWORK_POLICY.equals(tag)) { } else if (TAG_NETWORK_POLICY.equals(tag)) {
final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE); int templateType = readIntAttribute(in, ATTR_NETWORK_TEMPLATE);
final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID); final String subscriberId = in.getAttributeValue(null, ATTR_SUBSCRIBER_ID);
final String networkId; final String networkId;
final int subscriberIdMatchRule;
final int templateMeteredness;
if (version >= VERSION_ADDED_NETWORK_ID) { if (version >= VERSION_ADDED_NETWORK_ID) {
networkId = in.getAttributeValue(null, ATTR_NETWORK_ID); networkId = in.getAttributeValue(null, ATTR_NETWORK_ID);
} else { } else {
networkId = null; networkId = null;
} }
if (version >= VERSION_SUPPORTED_CARRIER_USAGE) {
subscriberIdMatchRule = readIntAttribute(in,
ATTR_SUBSCRIBER_ID_MATCH_RULE);
templateMeteredness = readIntAttribute(in, ATTR_TEMPLATE_METERED);
} else {
subscriberIdMatchRule = NetworkTemplate.SUBSCRIBER_ID_MATCH_RULE_EXACT;
if (templateType == MATCH_MOBILE) {
Log.d(TAG, "Update template match rule from mobile to carrier and"
+ " force to metered");
templateType = MATCH_CARRIER;
templateMeteredness = METERED_YES;
} else {
templateMeteredness = METERED_ALL;
}
}
final RecurrenceRule cycleRule; final RecurrenceRule cycleRule;
if (version >= VERSION_ADDED_CYCLE) { if (version >= VERSION_ADDED_CYCLE) {
final String start = readStringAttribute(in, ATTR_CYCLE_START); final String start = readStringAttribute(in, ATTR_CYCLE_START);
@@ -2391,7 +2421,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
if (version >= VERSION_ADDED_METERED) { if (version >= VERSION_ADDED_METERED) {
metered = readBooleanAttribute(in, ATTR_METERED); metered = readBooleanAttribute(in, ATTR_METERED);
} else { } else {
switch (networkTemplate) { switch (templateType) {
case MATCH_MOBILE: case MATCH_MOBILE:
metered = true; metered = true;
break; break;
@@ -2411,9 +2441,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} else { } else {
inferred = false; inferred = false;
} }
final NetworkTemplate template = new NetworkTemplate(templateType,
final NetworkTemplate template = new NetworkTemplate(networkTemplate, subscriberId, new String[] { subscriberId },
subscriberId, networkId); networkId, templateMeteredness, NetworkStats.ROAMING_ALL,
NetworkStats.DEFAULT_NETWORK_ALL, NetworkTemplate.NETWORK_TYPE_ALL,
NetworkTemplate.OEM_MANAGED_ALL, subscriberIdMatchRule);
if (template.isPersistable()) { if (template.isPersistable()) {
mNetworkPolicy.put(template, new NetworkPolicy(template, cycleRule, mNetworkPolicy.put(template, new NetworkPolicy(template, cycleRule,
warningBytes, limitBytes, lastWarningSnooze, warningBytes, limitBytes, lastWarningSnooze,
@@ -2621,10 +2653,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
if (subscriberId != null) { if (subscriberId != null) {
out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId); out.attribute(null, ATTR_SUBSCRIBER_ID, subscriberId);
} }
writeIntAttribute(out, ATTR_SUBSCRIBER_ID_MATCH_RULE,
template.getSubscriberIdMatchRule());
final String networkId = template.getNetworkId(); final String networkId = template.getNetworkId();
if (networkId != null) { if (networkId != null) {
out.attribute(null, ATTR_NETWORK_ID, networkId); out.attribute(null, ATTR_NETWORK_ID, networkId);
} }
writeIntAttribute(out, ATTR_TEMPLATE_METERED,
template.getMeteredness());
writeStringAttribute(out, ATTR_CYCLE_START, writeStringAttribute(out, ATTR_CYCLE_START,
RecurrenceRule.convertZonedDateTime(policy.cycleRule.start)); RecurrenceRule.convertZonedDateTime(policy.cycleRule.start));
writeStringAttribute(out, ATTR_CYCLE_END, writeStringAttribute(out, ATTR_CYCLE_END,
@@ -3492,8 +3528,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final String subscriberId = mSubIdToSubscriberId.get(subId, null); final String subscriberId = mSubIdToSubscriberId.get(subId, null);
if (subscriberId != null) { if (subscriberId != null) {
ensureActiveMobilePolicyAL(subId, subscriberId); ensureActiveCarrierPolicyAL(subId, subscriberId);
maybeUpdateMobilePolicyCycleAL(subId, subscriberId); maybeUpdateCarrierPolicyCycleAL(subId, subscriberId);
} else { } else {
Slog.wtf(TAG, "Missing subscriberId for subId " + subId); Slog.wtf(TAG, "Missing subscriberId for subId " + subId);
} }
@@ -5534,11 +5570,15 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
return; return;
} }
// Turn mobile data limit off // Turn carrier/mobile data limit off
NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName()); NetworkPolicy[] policies = getNetworkPolicies(mContext.getOpPackageName());
NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriber); NetworkTemplate templateCarrier = buildTemplateCarrierMetered(subscriber);
NetworkTemplate templateMobile = buildTemplateMobileAll(subscriber);
for (NetworkPolicy policy : policies) { for (NetworkPolicy policy : policies) {
if (policy.template.equals(template)) { // All policies loaded from disk will be carrier templates, and setting will also only
// set carrier templates, but we clear mobile templates just in case one is set by
// some other caller
if (policy.template.equals(templateCarrier) || policy.template.equals(templateMobile)) {
policy.limitBytes = NetworkPolicy.LIMIT_DISABLED; policy.limitBytes = NetworkPolicy.LIMIT_DISABLED;
policy.inferred = false; policy.inferred = false;
policy.clearSnooze(); policy.clearSnooze();

View File

@@ -0,0 +1,6 @@
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<policy-list version="12" restrictBackground="false">
<network-policy networkTemplate="1" subscriberId="466977604504520" cycleStart="2020-01-09T00:00+08:00[Asia/Taipei]" cyclePeriod="P1M" warningBytes="2147483648" limitBytes="-1" lastWarningSnooze="-1" lastLimitSnooze="-1" metered="true" inferred="true" />
</policy-list>
<whitelist />

View File

@@ -0,0 +1,5 @@
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<policy-list version="13" restrictBackground="false">
<network-policy networkTemplate="4" subscriberIdMatchRule="1" networkId="TEST_SSID" templateMetered="0" cycleStart="2020-01-09T00:00+08:00[Asia/Taipei]" cyclePeriod="P1M" warningBytes="2147483648" limitBytes="-1" lastWarningSnooze="-1" lastLimitSnooze="-1" metered="true" inferred="true" />
</policy-list>
<whitelist />

View File

@@ -50,10 +50,12 @@ import static android.net.NetworkPolicyManager.uidPoliciesToString;
import static android.net.NetworkPolicyManager.uidRulesToString; import static android.net.NetworkPolicyManager.uidRulesToString;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.net.NetworkStats.IFACE_ALL; import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.METERED_NO;
import static android.net.NetworkStats.METERED_YES;
import static android.net.NetworkStats.SET_ALL; import static android.net.NetworkStats.SET_ALL;
import static android.net.NetworkStats.TAG_ALL; import static android.net.NetworkStats.TAG_ALL;
import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkTemplate.buildTemplateMobileAll; import static android.net.NetworkTemplate.buildTemplateCarrierMetered;
import static android.net.NetworkTemplate.buildTemplateWifi; import static android.net.NetworkTemplate.buildTemplateWifi;
import static android.net.TrafficStats.MB_IN_BYTES; import static android.net.TrafficStats.MB_IN_BYTES;
import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED; import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
@@ -229,7 +231,8 @@ public class NetworkPolicyManagerServiceTest {
private static final int TEST_NET_ID = 24; private static final int TEST_NET_ID = 24;
private static NetworkTemplate sTemplateWifi = buildTemplateWifi(TEST_SSID); private static NetworkTemplate sTemplateWifi = buildTemplateWifi(TEST_SSID);
private static NetworkTemplate sTemplateMobileAll = buildTemplateMobileAll(TEST_IMSI); private static NetworkTemplate sTemplateCarrierMetered =
buildTemplateCarrierMetered(TEST_IMSI);
/** /**
* Path on assets where files used by {@link NetPolicyXml} are located. * Path on assets where files used by {@link NetPolicyXml} are located.
@@ -450,7 +453,7 @@ public class NetworkPolicyManagerServiceTest {
verify(mNetworkManager).registerObserver(networkObserver.capture()); verify(mNetworkManager).registerObserver(networkObserver.capture());
mNetworkObserver = networkObserver.getValue(); mNetworkObserver = networkObserver.getValue();
NetworkPolicy defaultPolicy = mService.buildDefaultMobilePolicy(0, ""); NetworkPolicy defaultPolicy = mService.buildDefaultCarrierPolicy(0, "");
mDefaultWarningBytes = defaultPolicy.warningBytes; mDefaultWarningBytes = defaultPolicy.warningBytes;
mDefaultLimitBytes = defaultPolicy.limitBytes; mDefaultLimitBytes = defaultPolicy.limitBytes;
} }
@@ -1229,7 +1232,7 @@ public class NetworkPolicyManagerServiceTest {
reset(mTelephonyManager, mNetworkManager, mNotifManager); reset(mTelephonyManager, mNetworkManager, mNotifManager);
TelephonyManager tmSub = expectMobileDefaults(); TelephonyManager tmSub = expectMobileDefaults();
mService.snoozeLimit(NetworkTemplate.buildTemplateMobileAll(TEST_IMSI)); mService.snoozeLimit(NetworkTemplate.buildTemplateCarrierMetered(TEST_IMSI));
mService.updateNetworks(); mService.updateNetworks();
verify(tmSub, atLeastOnce()).setPolicyDataEnabled(true); verify(tmSub, atLeastOnce()).setPolicyDataEnabled(true);
@@ -1482,7 +1485,7 @@ public class NetworkPolicyManagerServiceTest {
assertEquals(mDefaultLimitBytes, actualLimitBytes); assertEquals(mDefaultLimitBytes, actualLimitBytes);
} }
private PersistableBundle setupUpdateMobilePolicyCycleTests() throws RemoteException { private PersistableBundle setupUpdateCarrierPolicyCycleTests() throws RemoteException {
when(mConnManager.getAllNetworkStateSnapshots()) when(mConnManager.getAllNetworkStateSnapshots())
.thenReturn(new ArrayList<NetworkStateSnapshot>()); .thenReturn(new ArrayList<NetworkStateSnapshot>());
@@ -1490,19 +1493,19 @@ public class NetworkPolicyManagerServiceTest {
PersistableBundle bundle = CarrierConfigManager.getDefaultConfig(); PersistableBundle bundle = CarrierConfigManager.getDefaultConfig();
when(mCarrierConfigManager.getConfigForSubId(FAKE_SUB_ID)).thenReturn(bundle); when(mCarrierConfigManager.getConfigForSubId(FAKE_SUB_ID)).thenReturn(bundle);
setNetworkPolicies(buildDefaultFakeMobilePolicy()); setNetworkPolicies(buildDefaultFakeCarrierPolicy());
return bundle; return bundle;
} }
@Test @Test
public void testUpdateMobilePolicyCycleWithNullConfig() throws RemoteException { public void testUpdateCarrierPolicyCycleWithNullConfig() throws RemoteException {
when(mConnManager.getAllNetworkStateSnapshots()) when(mConnManager.getAllNetworkStateSnapshots())
.thenReturn(new ArrayList<NetworkStateSnapshot>()); .thenReturn(new ArrayList<NetworkStateSnapshot>());
setupTelephonySubscriptionManagers(FAKE_SUB_ID, FAKE_SUBSCRIBER_ID); setupTelephonySubscriptionManagers(FAKE_SUB_ID, FAKE_SUBSCRIBER_ID);
when(mCarrierConfigManager.getConfigForSubId(FAKE_SUB_ID)).thenReturn(null); when(mCarrierConfigManager.getConfigForSubId(FAKE_SUB_ID)).thenReturn(null);
setNetworkPolicies(buildDefaultFakeMobilePolicy()); setNetworkPolicies(buildDefaultFakeCarrierPolicy());
// smoke test to make sure no errors are raised // smoke test to make sure no errors are raised
mServiceContext.sendBroadcast( mServiceContext.sendBroadcast(
new Intent(ACTION_CARRIER_CONFIG_CHANGED) new Intent(ACTION_CARRIER_CONFIG_CHANGED)
@@ -1513,8 +1516,8 @@ public class NetworkPolicyManagerServiceTest {
} }
@Test @Test
public void testUpdateMobilePolicyCycleWithInvalidConfig() throws RemoteException { public void testUpdateCarrierPolicyCycleWithInvalidConfig() throws RemoteException {
PersistableBundle bundle = setupUpdateMobilePolicyCycleTests(); PersistableBundle bundle = setupUpdateCarrierPolicyCycleTests();
// Test with an invalid CarrierConfig, there should be no changes or crashes. // Test with an invalid CarrierConfig, there should be no changes or crashes.
bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, -100); bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, -100);
bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, -100); bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, -100);
@@ -1529,8 +1532,8 @@ public class NetworkPolicyManagerServiceTest {
} }
@Test @Test
public void testUpdateMobilePolicyCycleWithDefaultConfig() throws RemoteException { public void testUpdateCarrierPolicyCycleWithDefaultConfig() throws RemoteException {
PersistableBundle bundle = setupUpdateMobilePolicyCycleTests(); PersistableBundle bundle = setupUpdateCarrierPolicyCycleTests();
// Test that we respect the platform values when told to // Test that we respect the platform values when told to
bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT,
DATA_CYCLE_USE_PLATFORM_DEFAULT); DATA_CYCLE_USE_PLATFORM_DEFAULT);
@@ -1548,11 +1551,11 @@ public class NetworkPolicyManagerServiceTest {
} }
@Test @Test
public void testUpdateMobilePolicyCycleWithUserOverrides() throws RemoteException { public void testUpdateCarrierPolicyCycleWithUserOverrides() throws RemoteException {
PersistableBundle bundle = setupUpdateMobilePolicyCycleTests(); PersistableBundle bundle = setupUpdateCarrierPolicyCycleTests();
// inferred = false implies that a user manually modified this policy. // inferred = false implies that a user manually modified this policy.
NetworkPolicy policy = buildDefaultFakeMobilePolicy(); NetworkPolicy policy = buildDefaultFakeCarrierPolicy();
policy.inferred = false; policy.inferred = false;
setNetworkPolicies(policy); setNetworkPolicies(policy);
@@ -1571,8 +1574,8 @@ public class NetworkPolicyManagerServiceTest {
} }
@Test @Test
public void testUpdateMobilePolicyCycleUpdatesDataCycle() throws RemoteException { public void testUpdateCarrierPolicyCycleUpdatesDataCycle() throws RemoteException {
PersistableBundle bundle = setupUpdateMobilePolicyCycleTests(); PersistableBundle bundle = setupUpdateCarrierPolicyCycleTests();
bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31); bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, 9999); bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, 9999);
@@ -1586,8 +1589,8 @@ public class NetworkPolicyManagerServiceTest {
} }
@Test @Test
public void testUpdateMobilePolicyCycleDisableThresholds() throws RemoteException { public void testUpdateCarrierPolicyCycleDisableThresholds() throws RemoteException {
PersistableBundle bundle = setupUpdateMobilePolicyCycleTests(); PersistableBundle bundle = setupUpdateCarrierPolicyCycleTests();
bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31); bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
@@ -1603,8 +1606,8 @@ public class NetworkPolicyManagerServiceTest {
} }
@Test @Test
public void testUpdateMobilePolicyCycleRevertsToDefault() throws RemoteException { public void testUpdateCarrierPolicyCycleRevertsToDefault() throws RemoteException {
PersistableBundle bundle = setupUpdateMobilePolicyCycleTests(); PersistableBundle bundle = setupUpdateCarrierPolicyCycleTests();
bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31); bundle.putInt(CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT, 31);
bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, bundle.putLong(CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG,
@@ -1774,7 +1777,7 @@ public class NetworkPolicyManagerServiceTest {
@Test @Test
public void testSetNetworkPolicies_withNullPolicies_doesNotThrow() { public void testSetNetworkPolicies_withNullPolicies_doesNotThrow() {
NetworkPolicy[] policies = new NetworkPolicy[3]; NetworkPolicy[] policies = new NetworkPolicy[3];
policies[1] = buildDefaultFakeMobilePolicy(); policies[1] = buildDefaultFakeCarrierPolicy();
setNetworkPolicies(policies); setNetworkPolicies(policies);
assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes, assertNetworkPolicyEquals(DEFAULT_CYCLE_DAY, mDefaultWarningBytes, mDefaultLimitBytes,
@@ -1820,7 +1823,8 @@ public class NetworkPolicyManagerServiceTest {
// Set warning to 7KB and limit to 10KB. // Set warning to 7KB and limit to 10KB.
setNetworkPolicies(new NetworkPolicy( setNetworkPolicies(new NetworkPolicy(
sTemplateMobileAll, CYCLE_DAY, TIMEZONE_UTC, 7000L, 10000L, true)); sTemplateCarrierMetered, CYCLE_DAY, TIMEZONE_UTC, 7000L, 10000L,
true));
postMsgAndWaitForCompletion(); postMsgAndWaitForCompletion();
// Verifies that remaining quotas are set to providers. // Verifies that remaining quotas are set to providers.
@@ -1971,6 +1975,40 @@ public class NetworkPolicyManagerServiceTest {
} }
} }
@Test
@NetPolicyXml("network-policy-mobile.xml")
public void testStartToSupportCarrierUsagePolicy() throws Exception {
NetworkPolicy[] policies = mService.getNetworkPolicies(
mServiceContext.getOpPackageName());
assertEquals("Unexpected number of network policies", 1, policies.length);
NetworkPolicy actualPolicy = policies[0];
assertEquals("Unexpected template match rule in network policies",
NetworkTemplate.MATCH_CARRIER,
actualPolicy.template.getMatchRule());
assertEquals("Unexpected subscriberId match rule in network policies",
NetworkTemplate.SUBSCRIBER_ID_MATCH_RULE_EXACT,
actualPolicy.template.getSubscriberIdMatchRule());
assertEquals("Unexpected template meteredness in network policies",
METERED_YES, actualPolicy.template.getMeteredness());
}
@Test
@NetPolicyXml("network-policy-wifi-with-subscriberId-match-rule-all-and-templateMetered-no.xml")
public void testSupportedCarrierUsagePolicy() throws Exception {
NetworkPolicy[] policies = mService.getNetworkPolicies(
mServiceContext.getOpPackageName());
assertEquals("Unexpected number of network policies", 1, policies.length);
NetworkPolicy actualPolicy = policies[0];
assertEquals("Unexpected template match rule in network policies",
NetworkTemplate.MATCH_WIFI,
actualPolicy.template.getMatchRule());
assertEquals("Unexpected subscriberId match rule in network policies",
NetworkTemplate.SUBSCRIBER_ID_MATCH_RULE_ALL,
actualPolicy.template.getSubscriberIdMatchRule());
assertEquals("Unexpected template meteredness in network policies",
METERED_NO, actualPolicy.template.getMeteredness());
}
private String formatBlockedStateError(int uid, int rule, boolean metered, private String formatBlockedStateError(int uid, int rule, boolean metered,
boolean backgroundRestricted) { boolean backgroundRestricted) {
return String.format( return String.format(
@@ -2023,8 +2061,8 @@ public class NetworkPolicyManagerServiceTest {
return nc; return nc;
} }
private NetworkPolicy buildDefaultFakeMobilePolicy() { private NetworkPolicy buildDefaultFakeCarrierPolicy() {
NetworkPolicy p = mService.buildDefaultMobilePolicy(FAKE_SUB_ID, FAKE_SUBSCRIBER_ID); NetworkPolicy p = mService.buildDefaultCarrierPolicy(FAKE_SUB_ID, FAKE_SUBSCRIBER_ID);
// set a deterministic cycle date // set a deterministic cycle date
p.cycleRule = new RecurrenceRule( p.cycleRule = new RecurrenceRule(
p.cycleRule.start.withDayOfMonth(DEFAULT_CYCLE_DAY), p.cycleRule.start.withDayOfMonth(DEFAULT_CYCLE_DAY),
@@ -2032,9 +2070,9 @@ public class NetworkPolicyManagerServiceTest {
return p; return p;
} }
private static NetworkPolicy buildFakeMobilePolicy(int cycleDay, long warningBytes, private static NetworkPolicy buildFakeCarrierPolicy(int cycleDay, long warningBytes,
long limitBytes, boolean inferred) { long limitBytes, boolean inferred) {
final NetworkTemplate template = buildTemplateMobileAll(FAKE_SUBSCRIBER_ID); final NetworkTemplate template = buildTemplateCarrierMetered(FAKE_SUBSCRIBER_ID);
return new NetworkPolicy(template, cycleDay, TimeZone.getDefault().getID(), warningBytes, return new NetworkPolicy(template, cycleDay, TimeZone.getDefault().getID(), warningBytes,
limitBytes, SNOOZE_NEVER, SNOOZE_NEVER, true, inferred); limitBytes, SNOOZE_NEVER, SNOOZE_NEVER, true, inferred);
} }
@@ -2045,8 +2083,8 @@ public class NetworkPolicyManagerServiceTest {
mServiceContext.getOpPackageName()); mServiceContext.getOpPackageName());
assertEquals("Unexpected number of network policies", 1, policies.length); assertEquals("Unexpected number of network policies", 1, policies.length);
NetworkPolicy actualPolicy = policies[0]; NetworkPolicy actualPolicy = policies[0];
NetworkPolicy expectedPolicy = buildFakeMobilePolicy(expectedCycleDay, expectedWarningBytes, NetworkPolicy expectedPolicy = buildFakeCarrierPolicy(expectedCycleDay,
expectedLimitBytes, expectedInferred); expectedWarningBytes, expectedLimitBytes, expectedInferred);
assertEquals(expectedPolicy, actualPolicy); assertEquals(expectedPolicy, actualPolicy);
} }