Merge "APIs to disable data usage notifications." into pi-dev

This commit is contained in:
TreeHugger Robot
2018-04-11 23:05:03 +00:00
committed by Android (Google) Code Review
7 changed files with 118 additions and 39 deletions

View File

@@ -27213,6 +27213,7 @@ package android.net {
field public static final int NET_CAPABILITY_IMS = 4; // 0x4
field public static final int NET_CAPABILITY_INTERNET = 12; // 0xc
field public static final int NET_CAPABILITY_MMS = 0; // 0x0
field public static final int NET_CAPABILITY_NOT_CONGESTED = 20; // 0x14
field public static final int NET_CAPABILITY_NOT_METERED = 11; // 0xb
field public static final int NET_CAPABILITY_NOT_RESTRICTED = 13; // 0xd
field public static final int NET_CAPABILITY_NOT_ROAMING = 18; // 0x12
@@ -41693,7 +41694,10 @@ package android.telephony {
field public static final java.lang.String KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING = "config_plans_package_override_string";
field public static final java.lang.String KEY_CONFIG_TELEPHONY_USE_OWN_NUMBER_FOR_VOICEMAIL_BOOL = "config_telephony_use_own_number_for_voicemail_bool";
field public static final java.lang.String KEY_CSP_ENABLED_BOOL = "csp_enabled_bool";
field public static final java.lang.String KEY_DATA_LIMIT_NOTIFICATION_BOOL = "data_limit_notification_bool";
field public static final java.lang.String KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG = "data_limit_threshold_bytes_long";
field public static final java.lang.String KEY_DATA_RAPID_NOTIFICATION_BOOL = "data_rapid_notification_bool";
field public static final java.lang.String KEY_DATA_WARNING_NOTIFICATION_BOOL = "data_warning_notification_bool";
field public static final java.lang.String KEY_DATA_WARNING_THRESHOLD_BYTES_LONG = "data_warning_threshold_bytes_long";
field public static final java.lang.String KEY_DEFAULT_SIM_CALL_MANAGER_STRING = "default_sim_call_manager_string";
field public static final java.lang.String KEY_DEFAULT_VM_NUMBER_STRING = "default_vm_number_string";

View File

@@ -254,9 +254,8 @@ public final class NetworkCapabilities implements Parcelable {
/**
* Indicates that this network is not congested.
* <p>
* When a network is congested, the device should defer network traffic that
* can be done at a later time without breaking developer contracts.
* @hide
* When a network is congested, applications should defer network traffic
* that can be done at a later time, such as uploading analytics.
*/
public static final int NET_CAPABILITY_NOT_CONGESTED = 20;

View File

@@ -149,6 +149,10 @@ public class RecurrenceRule implements Parcelable {
}
};
public boolean isRecurring() {
return period != null;
}
@Deprecated
public boolean isMonthly() {
return start != null

View File

@@ -80,6 +80,9 @@ import static android.provider.Settings.Global.NETPOLICY_QUOTA_UNLIMITED;
import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED;
import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT;
import static android.telephony.CarrierConfigManager.KEY_DATA_LIMIT_NOTIFICATION_BOOL;
import static android.telephony.CarrierConfigManager.KEY_DATA_RAPID_NOTIFICATION_BOOL;
import static android.telephony.CarrierConfigManager.KEY_DATA_WARNING_NOTIFICATION_BOOL;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static com.android.internal.util.ArrayUtils.appendInt;
@@ -1093,8 +1096,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final long now = mClock.millis();
for (int i = mNetworkPolicy.size()-1; i >= 0; i--) {
final NetworkPolicy policy = mNetworkPolicy.valueAt(i);
final int subId = findRelevantSubId(policy.template);
// ignore policies that aren't relevant to user
if (!isTemplateRelevant(policy.template)) continue;
if (subId == INVALID_SUBSCRIPTION_ID) continue;
if (!policy.hasCycle()) continue;
final Pair<ZonedDateTime, ZonedDateTime> cycle = NetworkPolicyManager
@@ -1103,28 +1108,43 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final long cycleEnd = cycle.second.toInstant().toEpochMilli();
final long totalBytes = getTotalBytes(policy.template, cycleStart, cycleEnd);
// Notify when data usage is over warning/limit
if (policy.isOverLimit(totalBytes)) {
final boolean snoozedThisCycle = policy.lastLimitSnooze >= cycleStart;
if (snoozedThisCycle) {
enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes, null);
} else {
enqueueNotification(policy, TYPE_LIMIT, totalBytes, null);
notifyOverLimitNL(policy.template);
// Carrier might want to manage notifications themselves
final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
final boolean notifyWarning = getBooleanDefeatingNullable(config,
KEY_DATA_WARNING_NOTIFICATION_BOOL, true);
final boolean notifyLimit = getBooleanDefeatingNullable(config,
KEY_DATA_LIMIT_NOTIFICATION_BOOL, true);
final boolean notifyRapid = getBooleanDefeatingNullable(config,
KEY_DATA_RAPID_NOTIFICATION_BOOL, true);
// Notify when data usage is over warning
if (notifyWarning) {
if (policy.isOverWarning(totalBytes) && !policy.isOverLimit(totalBytes)) {
final boolean snoozedThisCycle = policy.lastWarningSnooze >= cycleStart;
if (!snoozedThisCycle) {
enqueueNotification(policy, TYPE_WARNING, totalBytes, null);
}
}
}
} else {
notifyUnderLimitNL(policy.template);
final boolean snoozedThisCycle = policy.lastWarningSnooze >= cycleStart;
if (policy.isOverWarning(totalBytes) && !snoozedThisCycle) {
enqueueNotification(policy, TYPE_WARNING, totalBytes, null);
// Notify when data usage is over limit
if (notifyLimit) {
if (policy.isOverLimit(totalBytes)) {
final boolean snoozedThisCycle = policy.lastLimitSnooze >= cycleStart;
if (snoozedThisCycle) {
enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes, null);
} else {
enqueueNotification(policy, TYPE_LIMIT, totalBytes, null);
notifyOverLimitNL(policy.template);
}
} else {
notifyUnderLimitNL(policy.template);
}
}
// Warn if average usage over last 4 days is on track to blow pretty
// far past the plan limits.
if (policy.limitBytes != LIMIT_DISABLED) {
if (notifyRapid && policy.limitBytes != LIMIT_DISABLED) {
final long recentDuration = TimeUnit.DAYS.toMillis(4);
final long recentStart = now - recentDuration;
final long recentEnd = now;
@@ -1201,27 +1221,26 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
* current device state, such as when
* {@link TelephonyManager#getSubscriberId()} matches. This is regardless of
* data connection status.
*
* @return relevant subId, or {@link #INVALID_SUBSCRIPTION_ID} when no
* matching subId found.
*/
private boolean isTemplateRelevant(NetworkTemplate template) {
if (template.isMatchRuleMobile()) {
final TelephonyManager tele = mContext.getSystemService(TelephonyManager.class);
final SubscriptionManager sub = mContext.getSystemService(SubscriptionManager.class);
private int findRelevantSubId(NetworkTemplate template) {
final TelephonyManager tele = mContext.getSystemService(TelephonyManager.class);
final SubscriptionManager sub = mContext.getSystemService(SubscriptionManager.class);
// Mobile template is relevant when any active subscriber matches
final int[] subIds = ArrayUtils.defeatNullable(sub.getActiveSubscriptionIdList());
for (int subId : subIds) {
final String subscriberId = tele.getSubscriberId(subId);
final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true,
true);
if (template.matches(probeIdent)) {
return true;
}
// Mobile template is relevant when any active subscriber matches
final int[] subIds = ArrayUtils.defeatNullable(sub.getActiveSubscriptionIdList());
for (int subId : subIds) {
final String subscriberId = tele.getSubscriberId(subId);
final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true,
true);
if (template.matches(probeIdent)) {
return subId;
}
return false;
} else {
return true;
}
return INVALID_SUBSCRIPTION_ID;
}
/**
@@ -3086,9 +3105,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// We can only override when carrier told us about plans
synchronized (mNetworkPoliciesSecondLock) {
if (ArrayUtils.isEmpty(mSubscriptionPlans.get(subId))) {
final SubscriptionPlan plan = getPrimarySubscriptionPlanLocked(subId);
if (plan == null
|| plan.getDataLimitBehavior() == SubscriptionPlan.LIMIT_BEHAVIOR_UNKNOWN) {
throw new IllegalStateException(
"Must provide SubscriptionPlan information before overriding");
"Must provide valid SubscriptionPlan to enable overriding");
}
}
@@ -4831,7 +4852,21 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
@GuardedBy("mNetworkPoliciesSecondLock")
private SubscriptionPlan getPrimarySubscriptionPlanLocked(int subId) {
final SubscriptionPlan[] plans = mSubscriptionPlans.get(subId);
return ArrayUtils.isEmpty(plans) ? null : plans[0];
if (!ArrayUtils.isEmpty(plans)) {
for (SubscriptionPlan plan : plans) {
if (plan.getCycleRule().isRecurring()) {
// Recurring plans will always have an active cycle
return plan;
} else {
// Non-recurring plans need manual test for active cycle
final Range<ZonedDateTime> cycle = plan.cycleIterator().next();
if (cycle.contains(ZonedDateTime.now(mClock))) {
return plan;
}
}
}
}
return null;
}
/**
@@ -4878,6 +4913,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
return (val != null) ? val : new NetworkState[0];
}
private static boolean getBooleanDefeatingNullable(@Nullable PersistableBundle bundle,
String key, boolean defaultValue) {
return (bundle != null) ? bundle.getBoolean(key, defaultValue) : defaultValue;
}
private class NotificationId {
private final String mTag;
private final int mId;

View File

@@ -1714,6 +1714,8 @@ public class NetworkPolicyManagerServiceTest {
}
private void expectNetworkState(boolean roaming) throws Exception {
when(mCarrierConfigManager.getConfigForSubId(eq(TEST_SUB_ID)))
.thenReturn(CarrierConfigManager.getDefaultConfig());
when(mConnManager.getAllNetworkState()).thenReturn(new NetworkState[] {
new NetworkState(buildNetworkInfo(),
buildLinkProperties(TEST_IFACE),

View File

@@ -1683,6 +1683,14 @@ public class CarrierConfigManager {
public static final String KEY_DATA_WARNING_THRESHOLD_BYTES_LONG =
"data_warning_threshold_bytes_long";
/**
* Controls if the device should automatically notify the user as they reach
* their cellular data warning. When set to {@code false} the carrier is
* expected to have implemented their own notification mechanism.
*/
public static final String KEY_DATA_WARNING_NOTIFICATION_BOOL =
"data_warning_notification_bool";
/**
* Controls the cellular data limit.
* <p>
@@ -1697,6 +1705,22 @@ public class CarrierConfigManager {
public static final String KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG =
"data_limit_threshold_bytes_long";
/**
* Controls if the device should automatically notify the user as they reach
* their cellular data limit. When set to {@code false} the carrier is
* expected to have implemented their own notification mechanism.
*/
public static final String KEY_DATA_LIMIT_NOTIFICATION_BOOL =
"data_limit_notification_bool";
/**
* Controls if the device should automatically notify the user when rapid
* cellular data usage is observed. When set to {@code false} the carrier is
* expected to have implemented their own notification mechanism.
*/
public static final String KEY_DATA_RAPID_NOTIFICATION_BOOL =
"data_rapid_notification_bool";
/**
* Offset to be reduced from rsrp threshold while calculating signal strength level.
* @hide
@@ -2165,7 +2189,10 @@ public class CarrierConfigManager {
sDefaults.putInt(KEY_MONTHLY_DATA_CYCLE_DAY_INT, DATA_CYCLE_USE_PLATFORM_DEFAULT);
sDefaults.putLong(KEY_DATA_WARNING_THRESHOLD_BYTES_LONG, DATA_CYCLE_USE_PLATFORM_DEFAULT);
sDefaults.putBoolean(KEY_DATA_WARNING_NOTIFICATION_BOOL, true);
sDefaults.putLong(KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG, DATA_CYCLE_USE_PLATFORM_DEFAULT);
sDefaults.putBoolean(KEY_DATA_LIMIT_NOTIFICATION_BOOL, true);
sDefaults.putBoolean(KEY_DATA_RAPID_NOTIFICATION_BOOL, true);
// Rat families: {GPRS, EDGE}, {EVDO, EVDO_A, EVDO_B}, {UMTS, HSPA, HSDPA, HSUPA, HSPAP},
// {LTE, LTE_CA}

View File

@@ -254,6 +254,9 @@ public final class SubscriptionPlan implements Parcelable {
* @param period The period after which the plan automatically recurs.
*/
public static Builder createRecurring(ZonedDateTime start, Period period) {
if (period.isZero() || period.isNegative()) {
throw new IllegalArgumentException("Period " + period + " must be positive");
}
return new Builder(start, null, period);
}