Merge "Support snoozing of data warning notification."
This commit is contained in:
@@ -43,7 +43,7 @@ interface INetworkPolicyManager {
|
|||||||
NetworkPolicy[] getNetworkPolicies();
|
NetworkPolicy[] getNetworkPolicies();
|
||||||
|
|
||||||
/** Snooze limit on policy matching given template. */
|
/** Snooze limit on policy matching given template. */
|
||||||
void snoozePolicy(in NetworkTemplate template);
|
void snoozeLimit(in NetworkTemplate template);
|
||||||
|
|
||||||
/** Control if background data is restricted system-wide. */
|
/** Control if background data is restricted system-wide. */
|
||||||
void setRestrictBackground(boolean restrictBackground);
|
void setRestrictBackground(boolean restrictBackground);
|
||||||
|
|||||||
@@ -38,18 +38,25 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
|
|||||||
public int cycleDay;
|
public int cycleDay;
|
||||||
public long warningBytes;
|
public long warningBytes;
|
||||||
public long limitBytes;
|
public long limitBytes;
|
||||||
public long lastSnooze;
|
public long lastWarningSnooze;
|
||||||
|
public long lastLimitSnooze;
|
||||||
public boolean metered;
|
public boolean metered;
|
||||||
|
|
||||||
private static final long DEFAULT_MTU = 1500;
|
private static final long DEFAULT_MTU = 1500;
|
||||||
|
|
||||||
public NetworkPolicy(NetworkTemplate template, int cycleDay, long warningBytes, long limitBytes,
|
public NetworkPolicy(NetworkTemplate template, int cycleDay, long warningBytes,
|
||||||
long lastSnooze, boolean metered) {
|
long limitBytes, boolean metered) {
|
||||||
|
this(template, cycleDay, warningBytes, limitBytes, SNOOZE_NEVER, SNOOZE_NEVER, metered);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NetworkPolicy(NetworkTemplate template, int cycleDay, long warningBytes,
|
||||||
|
long limitBytes, long lastWarningSnooze, long lastLimitSnooze, boolean metered) {
|
||||||
this.template = checkNotNull(template, "missing NetworkTemplate");
|
this.template = checkNotNull(template, "missing NetworkTemplate");
|
||||||
this.cycleDay = cycleDay;
|
this.cycleDay = cycleDay;
|
||||||
this.warningBytes = warningBytes;
|
this.warningBytes = warningBytes;
|
||||||
this.limitBytes = limitBytes;
|
this.limitBytes = limitBytes;
|
||||||
this.lastSnooze = lastSnooze;
|
this.lastWarningSnooze = lastWarningSnooze;
|
||||||
|
this.lastLimitSnooze = lastLimitSnooze;
|
||||||
this.metered = metered;
|
this.metered = metered;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +65,8 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
|
|||||||
cycleDay = in.readInt();
|
cycleDay = in.readInt();
|
||||||
warningBytes = in.readLong();
|
warningBytes = in.readLong();
|
||||||
limitBytes = in.readLong();
|
limitBytes = in.readLong();
|
||||||
lastSnooze = in.readLong();
|
lastWarningSnooze = in.readLong();
|
||||||
|
lastLimitSnooze = in.readLong();
|
||||||
metered = in.readInt() != 0;
|
metered = in.readInt() != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +76,8 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
|
|||||||
dest.writeInt(cycleDay);
|
dest.writeInt(cycleDay);
|
||||||
dest.writeLong(warningBytes);
|
dest.writeLong(warningBytes);
|
||||||
dest.writeLong(limitBytes);
|
dest.writeLong(limitBytes);
|
||||||
dest.writeLong(lastSnooze);
|
dest.writeLong(lastWarningSnooze);
|
||||||
|
dest.writeLong(lastLimitSnooze);
|
||||||
dest.writeInt(metered ? 1 : 0);
|
dest.writeInt(metered ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,6 +86,13 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test if given measurement is over {@link #warningBytes}.
|
||||||
|
*/
|
||||||
|
public boolean isOverWarning(long totalBytes) {
|
||||||
|
return warningBytes != WARNING_DISABLED && totalBytes >= warningBytes;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if given measurement is near enough to {@link #limitBytes} to be
|
* Test if given measurement is near enough to {@link #limitBytes} to be
|
||||||
* considered over-limit.
|
* considered over-limit.
|
||||||
@@ -88,6 +104,14 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
|
|||||||
return limitBytes != LIMIT_DISABLED && totalBytes >= limitBytes;
|
return limitBytes != LIMIT_DISABLED && totalBytes >= limitBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear any existing snooze values, setting to {@link #SNOOZE_NEVER}.
|
||||||
|
*/
|
||||||
|
public void clearSnooze() {
|
||||||
|
lastWarningSnooze = SNOOZE_NEVER;
|
||||||
|
lastLimitSnooze = SNOOZE_NEVER;
|
||||||
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
public int compareTo(NetworkPolicy another) {
|
public int compareTo(NetworkPolicy another) {
|
||||||
if (another == null || another.limitBytes == LIMIT_DISABLED) {
|
if (another == null || another.limitBytes == LIMIT_DISABLED) {
|
||||||
@@ -103,7 +127,8 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hashCode(template, cycleDay, warningBytes, limitBytes, lastSnooze, metered);
|
return Objects.hashCode(template, cycleDay, warningBytes, limitBytes, lastWarningSnooze,
|
||||||
|
lastLimitSnooze, metered);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -111,8 +136,10 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
|
|||||||
if (obj instanceof NetworkPolicy) {
|
if (obj instanceof NetworkPolicy) {
|
||||||
final NetworkPolicy other = (NetworkPolicy) obj;
|
final NetworkPolicy other = (NetworkPolicy) obj;
|
||||||
return cycleDay == other.cycleDay && warningBytes == other.warningBytes
|
return cycleDay == other.cycleDay && warningBytes == other.warningBytes
|
||||||
&& limitBytes == other.limitBytes && lastSnooze == other.lastSnooze
|
&& limitBytes == other.limitBytes
|
||||||
&& metered == other.metered && Objects.equal(template, other.template);
|
&& lastWarningSnooze == other.lastWarningSnooze
|
||||||
|
&& lastLimitSnooze == other.lastLimitSnooze && metered == other.metered
|
||||||
|
&& Objects.equal(template, other.template);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -120,8 +147,9 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "NetworkPolicy[" + template + "]: cycleDay=" + cycleDay + ", warningBytes="
|
return "NetworkPolicy[" + template + "]: cycleDay=" + cycleDay + ", warningBytes="
|
||||||
+ warningBytes + ", limitBytes=" + limitBytes + ", lastSnooze=" + lastSnooze
|
+ warningBytes + ", limitBytes=" + limitBytes + ", lastWarningSnooze="
|
||||||
+ ", metered=" + metered;
|
+ lastWarningSnooze + ", lastLimitSnooze=" + lastLimitSnooze + ", metered="
|
||||||
|
+ metered;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Creator<NetworkPolicy> CREATOR = new Creator<NetworkPolicy>() {
|
public static final Creator<NetworkPolicy> CREATOR = new Creator<NetworkPolicy>() {
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ public class NetworkOverLimitActivity extends Activity {
|
|||||||
final INetworkPolicyManager policyService = INetworkPolicyManager.Stub.asInterface(
|
final INetworkPolicyManager policyService = INetworkPolicyManager.Stub.asInterface(
|
||||||
ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
|
ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
|
||||||
try {
|
try {
|
||||||
policyService.snoozePolicy(template);
|
policyService.snoozeLimit(template);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Slog.w(TAG, "problem snoozing network policy", e);
|
Slog.w(TAG, "problem snoozing network policy", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -154,6 +154,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
private static final int VERSION_ADDED_SNOOZE = 2;
|
private static final int VERSION_ADDED_SNOOZE = 2;
|
||||||
private static final int VERSION_ADDED_RESTRICT_BACKGROUND = 3;
|
private static final int VERSION_ADDED_RESTRICT_BACKGROUND = 3;
|
||||||
private static final int VERSION_ADDED_METERED = 4;
|
private static final int VERSION_ADDED_METERED = 4;
|
||||||
|
private static final int VERSION_SPLIT_SNOOZE = 5;
|
||||||
|
|
||||||
private static final long KB_IN_BYTES = 1024;
|
private static final long KB_IN_BYTES = 1024;
|
||||||
private static final long MB_IN_BYTES = KB_IN_BYTES * 1024;
|
private static final long MB_IN_BYTES = KB_IN_BYTES * 1024;
|
||||||
@@ -176,6 +177,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
private static final String ATTR_WARNING_BYTES = "warningBytes";
|
private static final String ATTR_WARNING_BYTES = "warningBytes";
|
||||||
private static final String ATTR_LIMIT_BYTES = "limitBytes";
|
private static final String ATTR_LIMIT_BYTES = "limitBytes";
|
||||||
private static final String ATTR_LAST_SNOOZE = "lastSnooze";
|
private static final String ATTR_LAST_SNOOZE = "lastSnooze";
|
||||||
|
private static final String ATTR_LAST_WARNING_SNOOZE = "lastWarningSnooze";
|
||||||
|
private static final String ATTR_LAST_LIMIT_SNOOZE = "lastLimitSnooze";
|
||||||
private static final String ATTR_METERED = "metered";
|
private static final String ATTR_METERED = "metered";
|
||||||
private static final String ATTR_UID = "uid";
|
private static final String ATTR_UID = "uid";
|
||||||
private static final String ATTR_POLICY = "policy";
|
private static final String ATTR_POLICY = "policy";
|
||||||
@@ -184,7 +187,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
|
|
||||||
// @VisibleForTesting
|
// @VisibleForTesting
|
||||||
public static final String ACTION_ALLOW_BACKGROUND =
|
public static final String ACTION_ALLOW_BACKGROUND =
|
||||||
"com.android.server.action.ACTION_ALLOW_BACKGROUND";
|
"com.android.server.net.action.ALLOW_BACKGROUND";
|
||||||
|
public static final String ACTION_SNOOZE_WARNING =
|
||||||
|
"com.android.server.net.action.SNOOZE_WARNING";
|
||||||
|
|
||||||
private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS;
|
private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS;
|
||||||
|
|
||||||
@@ -333,6 +338,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND);
|
final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND);
|
||||||
mContext.registerReceiver(mAllowReceiver, allowFilter, MANAGE_NETWORK_POLICY, mHandler);
|
mContext.registerReceiver(mAllowReceiver, allowFilter, MANAGE_NETWORK_POLICY, mHandler);
|
||||||
|
|
||||||
|
// listen for snooze warning from notifications
|
||||||
|
final IntentFilter snoozeWarningFilter = new IntentFilter(ACTION_SNOOZE_WARNING);
|
||||||
|
mContext.registerReceiver(mSnoozeWarningReceiver, snoozeWarningFilter,
|
||||||
|
MANAGE_NETWORK_POLICY, mHandler);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private IProcessObserver mProcessObserver = new IProcessObserver.Stub() {
|
private IProcessObserver mProcessObserver = new IProcessObserver.Stub() {
|
||||||
@@ -417,6 +427,21 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receiver that watches for {@link Notification} control of
|
||||||
|
* {@link NetworkPolicy#lastWarningSnooze}.
|
||||||
|
*/
|
||||||
|
private BroadcastReceiver mSnoozeWarningReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
// on background handler thread, and verified MANAGE_NETWORK_POLICY
|
||||||
|
// permission above.
|
||||||
|
|
||||||
|
final NetworkTemplate template = intent.getParcelableExtra(EXTRA_NETWORK_TEMPLATE);
|
||||||
|
performSnooze(template, TYPE_WARNING);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Observer that watches for {@link INetworkManagementService} alerts.
|
* Observer that watches for {@link INetworkManagementService} alerts.
|
||||||
*/
|
*/
|
||||||
@@ -458,7 +483,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
final long totalBytes = getTotalBytes(policy.template, start, end);
|
final long totalBytes = getTotalBytes(policy.template, start, end);
|
||||||
|
|
||||||
if (policy.isOverLimit(totalBytes)) {
|
if (policy.isOverLimit(totalBytes)) {
|
||||||
if (policy.lastSnooze >= start) {
|
if (policy.lastLimitSnooze >= start) {
|
||||||
enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes);
|
enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes);
|
||||||
} else {
|
} else {
|
||||||
enqueueNotification(policy, TYPE_LIMIT, totalBytes);
|
enqueueNotification(policy, TYPE_LIMIT, totalBytes);
|
||||||
@@ -468,7 +493,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
} else {
|
} else {
|
||||||
notifyUnderLimitLocked(policy.template);
|
notifyUnderLimitLocked(policy.template);
|
||||||
|
|
||||||
if (policy.warningBytes != WARNING_DISABLED && totalBytes >= policy.warningBytes) {
|
if (policy.isOverWarning(totalBytes) && policy.lastWarningSnooze < start) {
|
||||||
enqueueNotification(policy, TYPE_WARNING, totalBytes);
|
enqueueNotification(policy, TYPE_WARNING, totalBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -534,7 +559,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
final String tag = buildNotificationTag(policy, type);
|
final String tag = buildNotificationTag(policy, type);
|
||||||
final Notification.Builder builder = new Notification.Builder(mContext);
|
final Notification.Builder builder = new Notification.Builder(mContext);
|
||||||
builder.setOnlyAlertOnce(true);
|
builder.setOnlyAlertOnce(true);
|
||||||
builder.setOngoing(true);
|
builder.setWhen(0L);
|
||||||
|
|
||||||
final Resources res = mContext.getResources();
|
final Resources res = mContext.getResources();
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@@ -547,9 +572,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
builder.setContentTitle(title);
|
builder.setContentTitle(title);
|
||||||
builder.setContentText(body);
|
builder.setContentText(body);
|
||||||
|
|
||||||
final Intent intent = buildViewDataUsageIntent(policy.template);
|
final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template);
|
||||||
|
builder.setDeleteIntent(PendingIntent.getBroadcast(
|
||||||
|
mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT));
|
||||||
|
|
||||||
|
final Intent viewIntent = buildViewDataUsageIntent(policy.template);
|
||||||
builder.setContentIntent(PendingIntent.getActivity(
|
builder.setContentIntent(PendingIntent.getActivity(
|
||||||
mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
|
mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TYPE_LIMIT: {
|
case TYPE_LIMIT: {
|
||||||
@@ -574,6 +604,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
builder.setOngoing(true);
|
||||||
builder.setSmallIcon(R.drawable.stat_notify_disabled);
|
builder.setSmallIcon(R.drawable.stat_notify_disabled);
|
||||||
builder.setTicker(title);
|
builder.setTicker(title);
|
||||||
builder.setContentTitle(title);
|
builder.setContentTitle(title);
|
||||||
@@ -608,6 +639,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
builder.setOngoing(true);
|
||||||
builder.setSmallIcon(R.drawable.stat_notify_error);
|
builder.setSmallIcon(R.drawable.stat_notify_error);
|
||||||
builder.setTicker(title);
|
builder.setTicker(title);
|
||||||
builder.setContentTitle(title);
|
builder.setContentTitle(title);
|
||||||
@@ -720,10 +752,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
final long totalBytes = getTotalBytes(policy.template, start, end);
|
final long totalBytes = getTotalBytes(policy.template, start, end);
|
||||||
|
|
||||||
// disable data connection when over limit and not snoozed
|
// disable data connection when over limit and not snoozed
|
||||||
final boolean overLimit = policy.isOverLimit(totalBytes) && policy.lastSnooze < start;
|
final boolean overLimitWithoutSnooze = policy.isOverLimit(totalBytes)
|
||||||
final boolean enabled = !overLimit;
|
&& policy.lastLimitSnooze < start;
|
||||||
|
final boolean networkEnabled = !overLimitWithoutSnooze;
|
||||||
|
|
||||||
setNetworkTemplateEnabled(policy.template, enabled);
|
setNetworkTemplateEnabled(policy.template, networkEnabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -827,7 +860,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
// metered network, but no policy limit; we still need to
|
// metered network, but no policy limit; we still need to
|
||||||
// restrict apps, so push really high quota.
|
// restrict apps, so push really high quota.
|
||||||
quotaBytes = Long.MAX_VALUE;
|
quotaBytes = Long.MAX_VALUE;
|
||||||
} else if (policy.lastSnooze >= start) {
|
} else if (policy.lastLimitSnooze >= start) {
|
||||||
// snoozing past quota, but we still need to restrict apps,
|
// snoozing past quota, but we still need to restrict apps,
|
||||||
// so push really high quota.
|
// so push really high quota.
|
||||||
quotaBytes = Long.MAX_VALUE;
|
quotaBytes = Long.MAX_VALUE;
|
||||||
@@ -896,8 +929,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
final int cycleDay = time.monthDay;
|
final int cycleDay = time.monthDay;
|
||||||
|
|
||||||
final NetworkTemplate template = buildTemplateMobileAll(subscriberId);
|
final NetworkTemplate template = buildTemplateMobileAll(subscriberId);
|
||||||
mNetworkPolicy.put(template, new NetworkPolicy(
|
mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay, warningBytes,
|
||||||
template, cycleDay, warningBytes, LIMIT_DISABLED, SNOOZE_NEVER, true));
|
LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, true));
|
||||||
writePolicyLocked();
|
writePolicyLocked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -935,11 +968,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY);
|
final int cycleDay = readIntAttribute(in, ATTR_CYCLE_DAY);
|
||||||
final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES);
|
final long warningBytes = readLongAttribute(in, ATTR_WARNING_BYTES);
|
||||||
final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES);
|
final long limitBytes = readLongAttribute(in, ATTR_LIMIT_BYTES);
|
||||||
final long lastSnooze;
|
final long lastLimitSnooze;
|
||||||
if (version >= VERSION_ADDED_SNOOZE) {
|
if (version >= VERSION_SPLIT_SNOOZE) {
|
||||||
lastSnooze = readLongAttribute(in, ATTR_LAST_SNOOZE);
|
lastLimitSnooze = readLongAttribute(in, ATTR_LAST_LIMIT_SNOOZE);
|
||||||
|
} else if (version >= VERSION_ADDED_SNOOZE) {
|
||||||
|
lastLimitSnooze = readLongAttribute(in, ATTR_LAST_SNOOZE);
|
||||||
} else {
|
} else {
|
||||||
lastSnooze = SNOOZE_NEVER;
|
lastLimitSnooze = SNOOZE_NEVER;
|
||||||
}
|
}
|
||||||
final boolean metered;
|
final boolean metered;
|
||||||
if (version >= VERSION_ADDED_METERED) {
|
if (version >= VERSION_ADDED_METERED) {
|
||||||
@@ -955,11 +990,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
metered = false;
|
metered = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
final long lastWarningSnooze;
|
||||||
|
if (version >= VERSION_SPLIT_SNOOZE) {
|
||||||
|
lastWarningSnooze = readLongAttribute(in, ATTR_LAST_WARNING_SNOOZE);
|
||||||
|
} else {
|
||||||
|
lastWarningSnooze = SNOOZE_NEVER;
|
||||||
|
}
|
||||||
|
|
||||||
final NetworkTemplate template = new NetworkTemplate(
|
final NetworkTemplate template = new NetworkTemplate(
|
||||||
networkTemplate, subscriberId);
|
networkTemplate, subscriberId);
|
||||||
mNetworkPolicy.put(template, new NetworkPolicy(
|
mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay,
|
||||||
template, cycleDay, warningBytes, limitBytes, lastSnooze, metered));
|
warningBytes, limitBytes, lastWarningSnooze, lastLimitSnooze,
|
||||||
|
metered));
|
||||||
|
|
||||||
} else if (TAG_UID_POLICY.equals(tag)) {
|
} else if (TAG_UID_POLICY.equals(tag)) {
|
||||||
final int uid = readIntAttribute(in, ATTR_UID);
|
final int uid = readIntAttribute(in, ATTR_UID);
|
||||||
@@ -1014,7 +1056,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
out.startDocument(null, true);
|
out.startDocument(null, true);
|
||||||
|
|
||||||
out.startTag(null, TAG_POLICY_LIST);
|
out.startTag(null, TAG_POLICY_LIST);
|
||||||
writeIntAttribute(out, ATTR_VERSION, VERSION_ADDED_METERED);
|
writeIntAttribute(out, ATTR_VERSION, VERSION_SPLIT_SNOOZE);
|
||||||
writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground);
|
writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground);
|
||||||
|
|
||||||
// write all known network policies
|
// write all known network policies
|
||||||
@@ -1030,7 +1072,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
writeIntAttribute(out, ATTR_CYCLE_DAY, policy.cycleDay);
|
writeIntAttribute(out, ATTR_CYCLE_DAY, policy.cycleDay);
|
||||||
writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes);
|
writeLongAttribute(out, ATTR_WARNING_BYTES, policy.warningBytes);
|
||||||
writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes);
|
writeLongAttribute(out, ATTR_LIMIT_BYTES, policy.limitBytes);
|
||||||
writeLongAttribute(out, ATTR_LAST_SNOOZE, policy.lastSnooze);
|
writeLongAttribute(out, ATTR_LAST_WARNING_SNOOZE, policy.lastWarningSnooze);
|
||||||
|
writeLongAttribute(out, ATTR_LAST_LIMIT_SNOOZE, policy.lastLimitSnooze);
|
||||||
writeBooleanAttribute(out, ATTR_METERED, policy.metered);
|
writeBooleanAttribute(out, ATTR_METERED, policy.metered);
|
||||||
out.endTag(null, TAG_NETWORK_POLICY);
|
out.endTag(null, TAG_NETWORK_POLICY);
|
||||||
}
|
}
|
||||||
@@ -1141,9 +1184,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void snoozePolicy(NetworkTemplate template) {
|
public void snoozeLimit(NetworkTemplate template) {
|
||||||
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
|
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
|
||||||
|
performSnooze(template, TYPE_LIMIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performSnooze(NetworkTemplate template, int type) {
|
||||||
maybeRefreshTrustedTime();
|
maybeRefreshTrustedTime();
|
||||||
final long currentTime = currentTimeMillis();
|
final long currentTime = currentTimeMillis();
|
||||||
synchronized (mRulesLock) {
|
synchronized (mRulesLock) {
|
||||||
@@ -1153,7 +1199,16 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
throw new IllegalArgumentException("unable to find policy for " + template);
|
throw new IllegalArgumentException("unable to find policy for " + template);
|
||||||
}
|
}
|
||||||
|
|
||||||
policy.lastSnooze = currentTime;
|
switch (type) {
|
||||||
|
case TYPE_WARNING:
|
||||||
|
policy.lastWarningSnooze = currentTime;
|
||||||
|
break;
|
||||||
|
case TYPE_LIMIT:
|
||||||
|
policy.lastLimitSnooze = currentTime;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("unexpected type");
|
||||||
|
}
|
||||||
|
|
||||||
updateNetworkEnabledLocked();
|
updateNetworkEnabledLocked();
|
||||||
updateNetworkRulesLocked();
|
updateNetworkRulesLocked();
|
||||||
@@ -1246,12 +1301,17 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
synchronized (mRulesLock) {
|
synchronized (mRulesLock) {
|
||||||
if (argSet.contains("unsnooze")) {
|
if (argSet.contains("--unsnooze")) {
|
||||||
for (NetworkPolicy policy : mNetworkPolicy.values()) {
|
for (NetworkPolicy policy : mNetworkPolicy.values()) {
|
||||||
policy.lastSnooze = SNOOZE_NEVER;
|
policy.clearSnooze();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateNetworkEnabledLocked();
|
||||||
|
updateNetworkRulesLocked();
|
||||||
|
updateNotificationsLocked();
|
||||||
writePolicyLocked();
|
writePolicyLocked();
|
||||||
fout.println("Wiped snooze timestamps");
|
|
||||||
|
fout.println("Cleared snooze timestamps");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1599,6 +1659,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
|||||||
return new Intent(ACTION_ALLOW_BACKGROUND);
|
return new Intent(ACTION_ALLOW_BACKGROUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Intent buildSnoozeWarningIntent(NetworkTemplate template) {
|
||||||
|
final Intent intent = new Intent(ACTION_SNOOZE_WARNING);
|
||||||
|
intent.putExtra(EXTRA_NETWORK_TEMPLATE, template);
|
||||||
|
return intent;
|
||||||
|
}
|
||||||
|
|
||||||
private static Intent buildNetworkOverLimitIntent(NetworkTemplate template) {
|
private static Intent buildNetworkOverLimitIntent(NetworkTemplate template) {
|
||||||
final Intent intent = new Intent();
|
final Intent intent = new Intent();
|
||||||
intent.setComponent(new ComponentName(
|
intent.setComponent(new ComponentName(
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import static android.content.Intent.EXTRA_UID;
|
|||||||
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
|
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
|
||||||
import static android.net.ConnectivityManager.TYPE_WIFI;
|
import static android.net.ConnectivityManager.TYPE_WIFI;
|
||||||
import static android.net.NetworkPolicy.LIMIT_DISABLED;
|
import static android.net.NetworkPolicy.LIMIT_DISABLED;
|
||||||
import static android.net.NetworkPolicy.SNOOZE_NEVER;
|
|
||||||
import static android.net.NetworkPolicy.WARNING_DISABLED;
|
import static android.net.NetworkPolicy.WARNING_DISABLED;
|
||||||
import static android.net.NetworkPolicyManager.POLICY_NONE;
|
import static android.net.NetworkPolicyManager.POLICY_NONE;
|
||||||
import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
|
import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
|
||||||
@@ -256,41 +255,49 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testPidForegroundCombined() throws Exception {
|
public void testPidForegroundCombined() throws Exception {
|
||||||
|
IdleFuture idle;
|
||||||
|
|
||||||
// push all uid into background
|
// push all uid into background
|
||||||
|
idle = expectIdle();
|
||||||
mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false);
|
mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false);
|
||||||
mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false);
|
mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false);
|
||||||
mProcessObserver.onForegroundActivitiesChanged(PID_3, UID_B, false);
|
mProcessObserver.onForegroundActivitiesChanged(PID_3, UID_B, false);
|
||||||
waitUntilIdle();
|
idle.get();
|
||||||
assertFalse(mService.isUidForeground(UID_A));
|
assertFalse(mService.isUidForeground(UID_A));
|
||||||
assertFalse(mService.isUidForeground(UID_B));
|
assertFalse(mService.isUidForeground(UID_B));
|
||||||
|
|
||||||
// push one of the shared pids into foreground
|
// push one of the shared pids into foreground
|
||||||
|
idle = expectIdle();
|
||||||
mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, true);
|
mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, true);
|
||||||
waitUntilIdle();
|
idle.get();
|
||||||
assertTrue(mService.isUidForeground(UID_A));
|
assertTrue(mService.isUidForeground(UID_A));
|
||||||
assertFalse(mService.isUidForeground(UID_B));
|
assertFalse(mService.isUidForeground(UID_B));
|
||||||
|
|
||||||
// and swap another uid into foreground
|
// and swap another uid into foreground
|
||||||
|
idle = expectIdle();
|
||||||
mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false);
|
mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false);
|
||||||
mProcessObserver.onForegroundActivitiesChanged(PID_3, UID_B, true);
|
mProcessObserver.onForegroundActivitiesChanged(PID_3, UID_B, true);
|
||||||
waitUntilIdle();
|
idle.get();
|
||||||
assertFalse(mService.isUidForeground(UID_A));
|
assertFalse(mService.isUidForeground(UID_A));
|
||||||
assertTrue(mService.isUidForeground(UID_B));
|
assertTrue(mService.isUidForeground(UID_B));
|
||||||
|
|
||||||
// push both pid into foreground
|
// push both pid into foreground
|
||||||
|
idle = expectIdle();
|
||||||
mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true);
|
mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true);
|
||||||
mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, true);
|
mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, true);
|
||||||
waitUntilIdle();
|
idle.get();
|
||||||
assertTrue(mService.isUidForeground(UID_A));
|
assertTrue(mService.isUidForeground(UID_A));
|
||||||
|
|
||||||
// pull one out, should still be foreground
|
// pull one out, should still be foreground
|
||||||
|
idle = expectIdle();
|
||||||
mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false);
|
mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false);
|
||||||
waitUntilIdle();
|
idle.get();
|
||||||
assertTrue(mService.isUidForeground(UID_A));
|
assertTrue(mService.isUidForeground(UID_A));
|
||||||
|
|
||||||
// pull final pid out, should now be background
|
// pull final pid out, should now be background
|
||||||
|
idle = expectIdle();
|
||||||
mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false);
|
mProcessObserver.onForegroundActivitiesChanged(PID_2, UID_A, false);
|
||||||
waitUntilIdle();
|
idle.get();
|
||||||
assertFalse(mService.isUidForeground(UID_A));
|
assertFalse(mService.isUidForeground(UID_A));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,7 +441,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
|||||||
final long expectedCycle = parseTime("2007-11-05T00:00:00.000Z");
|
final long expectedCycle = parseTime("2007-11-05T00:00:00.000Z");
|
||||||
|
|
||||||
final NetworkPolicy policy = new NetworkPolicy(
|
final NetworkPolicy policy = new NetworkPolicy(
|
||||||
sTemplateWifi, 5, 1024L, 1024L, SNOOZE_NEVER, false);
|
sTemplateWifi, 5, 1024L, 1024L, false);
|
||||||
final long actualCycle = computeLastCycleBoundary(currentTime, policy);
|
final long actualCycle = computeLastCycleBoundary(currentTime, policy);
|
||||||
assertTimeEquals(expectedCycle, actualCycle);
|
assertTimeEquals(expectedCycle, actualCycle);
|
||||||
}
|
}
|
||||||
@@ -445,7 +452,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
|||||||
final long expectedCycle = parseTime("2007-10-20T00:00:00.000Z");
|
final long expectedCycle = parseTime("2007-10-20T00:00:00.000Z");
|
||||||
|
|
||||||
final NetworkPolicy policy = new NetworkPolicy(
|
final NetworkPolicy policy = new NetworkPolicy(
|
||||||
sTemplateWifi, 20, 1024L, 1024L, SNOOZE_NEVER, false);
|
sTemplateWifi, 20, 1024L, 1024L, false);
|
||||||
final long actualCycle = computeLastCycleBoundary(currentTime, policy);
|
final long actualCycle = computeLastCycleBoundary(currentTime, policy);
|
||||||
assertTimeEquals(expectedCycle, actualCycle);
|
assertTimeEquals(expectedCycle, actualCycle);
|
||||||
}
|
}
|
||||||
@@ -456,7 +463,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
|||||||
final long expectedCycle = parseTime("2007-01-30T00:00:00.000Z");
|
final long expectedCycle = parseTime("2007-01-30T00:00:00.000Z");
|
||||||
|
|
||||||
final NetworkPolicy policy = new NetworkPolicy(
|
final NetworkPolicy policy = new NetworkPolicy(
|
||||||
sTemplateWifi, 30, 1024L, 1024L, SNOOZE_NEVER, false);
|
sTemplateWifi, 30, 1024L, 1024L, false);
|
||||||
final long actualCycle = computeLastCycleBoundary(currentTime, policy);
|
final long actualCycle = computeLastCycleBoundary(currentTime, policy);
|
||||||
assertTimeEquals(expectedCycle, actualCycle);
|
assertTimeEquals(expectedCycle, actualCycle);
|
||||||
}
|
}
|
||||||
@@ -467,14 +474,14 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
|||||||
final long expectedCycle = parseTime("2007-02-28T23:59:59.000Z");
|
final long expectedCycle = parseTime("2007-02-28T23:59:59.000Z");
|
||||||
|
|
||||||
final NetworkPolicy policy = new NetworkPolicy(
|
final NetworkPolicy policy = new NetworkPolicy(
|
||||||
sTemplateWifi, 30, 1024L, 1024L, SNOOZE_NEVER, false);
|
sTemplateWifi, 30, 1024L, 1024L, false);
|
||||||
final long actualCycle = computeLastCycleBoundary(currentTime, policy);
|
final long actualCycle = computeLastCycleBoundary(currentTime, policy);
|
||||||
assertTimeEquals(expectedCycle, actualCycle);
|
assertTimeEquals(expectedCycle, actualCycle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testNextCycleSane() throws Exception {
|
public void testNextCycleSane() throws Exception {
|
||||||
final NetworkPolicy policy = new NetworkPolicy(
|
final NetworkPolicy policy = new NetworkPolicy(
|
||||||
sTemplateWifi, 31, WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER, false);
|
sTemplateWifi, 31, WARNING_DISABLED, LIMIT_DISABLED, false);
|
||||||
final LinkedHashSet<Long> seen = new LinkedHashSet<Long>();
|
final LinkedHashSet<Long> seen = new LinkedHashSet<Long>();
|
||||||
|
|
||||||
// walk forwards, ensuring that cycle boundaries don't get stuck
|
// walk forwards, ensuring that cycle boundaries don't get stuck
|
||||||
@@ -489,7 +496,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
|||||||
|
|
||||||
public void testLastCycleSane() throws Exception {
|
public void testLastCycleSane() throws Exception {
|
||||||
final NetworkPolicy policy = new NetworkPolicy(
|
final NetworkPolicy policy = new NetworkPolicy(
|
||||||
sTemplateWifi, 31, WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER, false);
|
sTemplateWifi, 31, WARNING_DISABLED, LIMIT_DISABLED, false);
|
||||||
final LinkedHashSet<Long> seen = new LinkedHashSet<Long>();
|
final LinkedHashSet<Long> seen = new LinkedHashSet<Long>();
|
||||||
|
|
||||||
// walk backwards, ensuring that cycle boundaries look sane
|
// walk backwards, ensuring that cycle boundaries look sane
|
||||||
@@ -547,7 +554,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
|||||||
|
|
||||||
replay();
|
replay();
|
||||||
setNetworkPolicies(new NetworkPolicy(
|
setNetworkPolicies(new NetworkPolicy(
|
||||||
sTemplateWifi, CYCLE_DAY, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, SNOOZE_NEVER, false));
|
sTemplateWifi, CYCLE_DAY, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES, false));
|
||||||
future.get();
|
future.get();
|
||||||
verifyAndReset();
|
verifyAndReset();
|
||||||
}
|
}
|
||||||
@@ -604,9 +611,8 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
|||||||
future = expectMeteredIfacesChanged();
|
future = expectMeteredIfacesChanged();
|
||||||
|
|
||||||
replay();
|
replay();
|
||||||
setNetworkPolicies(
|
setNetworkPolicies(new NetworkPolicy(sTemplateWifi, CYCLE_DAY, 1 * MB_IN_BYTES,
|
||||||
new NetworkPolicy(sTemplateWifi, CYCLE_DAY, 1 * MB_IN_BYTES, 2 * MB_IN_BYTES,
|
2 * MB_IN_BYTES, false));
|
||||||
SNOOZE_NEVER, false));
|
|
||||||
future.get();
|
future.get();
|
||||||
verifyAndReset();
|
verifyAndReset();
|
||||||
}
|
}
|
||||||
@@ -698,7 +704,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
|||||||
tagFuture = expectEnqueueNotification();
|
tagFuture = expectEnqueueNotification();
|
||||||
|
|
||||||
replay();
|
replay();
|
||||||
mService.snoozePolicy(sTemplateWifi);
|
mService.snoozeLimit(sTemplateWifi);
|
||||||
assertNotificationType(TYPE_LIMIT_SNOOZED, tagFuture.get());
|
assertNotificationType(TYPE_LIMIT_SNOOZED, tagFuture.get());
|
||||||
future.get();
|
future.get();
|
||||||
verifyAndReset();
|
verifyAndReset();
|
||||||
@@ -736,9 +742,8 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
|||||||
future = expectMeteredIfacesChanged(TEST_IFACE);
|
future = expectMeteredIfacesChanged(TEST_IFACE);
|
||||||
|
|
||||||
replay();
|
replay();
|
||||||
setNetworkPolicies(
|
setNetworkPolicies(new NetworkPolicy(sTemplateWifi, CYCLE_DAY, WARNING_DISABLED,
|
||||||
new NetworkPolicy(sTemplateWifi, CYCLE_DAY, WARNING_DISABLED, LIMIT_DISABLED,
|
LIMIT_DISABLED, true));
|
||||||
SNOOZE_NEVER, true));
|
|
||||||
future.get();
|
future.get();
|
||||||
verifyAndReset();
|
verifyAndReset();
|
||||||
}
|
}
|
||||||
@@ -890,10 +895,10 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
|||||||
/**
|
/**
|
||||||
* Wait until {@link #mService} internal {@link Handler} is idle.
|
* Wait until {@link #mService} internal {@link Handler} is idle.
|
||||||
*/
|
*/
|
||||||
private void waitUntilIdle() throws Exception {
|
private IdleFuture expectIdle() {
|
||||||
final IdleFuture future = new IdleFuture();
|
final IdleFuture future = new IdleFuture();
|
||||||
mService.addIdleHandler(future);
|
mService.addIdleHandler(future);
|
||||||
future.get();
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void assertTimeEquals(long expected, long actual) {
|
private static void assertTimeEquals(long expected, long actual) {
|
||||||
|
|||||||
Reference in New Issue
Block a user