Reduce persist threshold for lower warning/limit.

Default is 2MB persist threshold, but even that can be substantial
for devices on 100MB/month plans. This change gradually reduces the
persist threshold up to 8x lower (256kb outstanding) based on lowest
active policy.

Bug: 5382676
Change-Id: Ief4e8cdb169bfb151a3d1b45722a8eaa01926508
This commit is contained in:
Jeff Sharkey
2012-05-02 18:11:52 -07:00
parent cfed18ad5b
commit c78bc60039
4 changed files with 107 additions and 34 deletions

View File

@@ -42,5 +42,7 @@ interface INetworkStatsService {
void setUidForeground(int uid, boolean uidForeground); void setUidForeground(int uid, boolean uidForeground);
/** Force update of statistics. */ /** Force update of statistics. */
void forceUpdate(); void forceUpdate();
/** Advise persistance threshold; may be overridden internally. */
void advisePersistThreshold(long thresholdBytes);
} }

View File

@@ -186,12 +186,12 @@ public class NetworkStatsCollection implements FileRotator.Reader {
if (history.size() == 0) return; if (history.size() == 0) return;
noteRecordedHistory(history.getStart(), history.getEnd(), history.getTotalBytes()); noteRecordedHistory(history.getStart(), history.getEnd(), history.getTotalBytes());
final NetworkStatsHistory existing = mStats.get(key); NetworkStatsHistory target = mStats.get(key);
if (existing != null) { if (target == null) {
existing.recordEntireHistory(history); target = new NetworkStatsHistory(history.getBucketDuration());
} else { mStats.put(key, target);
mStats.put(key, history);
} }
target.recordEntireHistory(history);
} }
/** /**

View File

@@ -17,6 +17,8 @@
package com.android.server.net; package com.android.server.net;
import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.TAG_NONE;
import static android.net.TrafficStats.KB_IN_BYTES;
import static android.net.TrafficStats.MB_IN_BYTES;
import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.internal.util.Preconditions.checkNotNull;
import android.net.NetworkStats; import android.net.NetworkStats;
@@ -25,6 +27,7 @@ import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate; import android.net.NetworkTemplate;
import android.net.TrafficStats; import android.net.TrafficStats;
import android.util.Log; import android.util.Log;
import android.util.MathUtils;
import android.util.Slog; import android.util.Slog;
import com.android.internal.util.FileRotator; import com.android.internal.util.FileRotator;
@@ -58,9 +61,9 @@ public class NetworkStatsRecorder {
private final String mCookie; private final String mCookie;
private final long mBucketDuration; private final long mBucketDuration;
private final long mPersistThresholdBytes;
private final boolean mOnlyTags; private final boolean mOnlyTags;
private long mPersistThresholdBytes = 2 * MB_IN_BYTES;
private NetworkStats mLastSnapshot; private NetworkStats mLastSnapshot;
private final NetworkStatsCollection mPending; private final NetworkStatsCollection mPending;
@@ -71,13 +74,12 @@ public class NetworkStatsRecorder {
private WeakReference<NetworkStatsCollection> mComplete; private WeakReference<NetworkStatsCollection> mComplete;
public NetworkStatsRecorder(FileRotator rotator, NonMonotonicObserver<String> observer, public NetworkStatsRecorder(FileRotator rotator, NonMonotonicObserver<String> observer,
String cookie, long bucketDuration, long persistThresholdBytes, boolean onlyTags) { String cookie, long bucketDuration, boolean onlyTags) {
mRotator = checkNotNull(rotator, "missing FileRotator"); mRotator = checkNotNull(rotator, "missing FileRotator");
mObserver = checkNotNull(observer, "missing NonMonotonicObserver"); mObserver = checkNotNull(observer, "missing NonMonotonicObserver");
mCookie = cookie; mCookie = cookie;
mBucketDuration = bucketDuration; mBucketDuration = bucketDuration;
mPersistThresholdBytes = persistThresholdBytes;
mOnlyTags = onlyTags; mOnlyTags = onlyTags;
mPending = new NetworkStatsCollection(bucketDuration); mPending = new NetworkStatsCollection(bucketDuration);
@@ -86,6 +88,12 @@ public class NetworkStatsRecorder {
mPendingRewriter = new CombiningRewriter(mPending); mPendingRewriter = new CombiningRewriter(mPending);
} }
public void setPersistThreshold(long thresholdBytes) {
if (LOGV) Slog.v(TAG, "setPersistThreshold() with " + thresholdBytes);
mPersistThresholdBytes = MathUtils.constrain(
thresholdBytes, 1 * KB_IN_BYTES, 100 * MB_IN_BYTES);
}
public void resetLocked() { public void resetLocked() {
mLastSnapshot = null; mLastSnapshot = null;
mPending.reset(); mPending.reset();
@@ -153,7 +161,7 @@ public class NetworkStatsRecorder {
continue; continue;
} }
// skip when no delta occured // skip when no delta occurred
if (entry.isEmpty()) continue; if (entry.isEmpty()) continue;
// only record tag data when requested // only record tag data when requested

View File

@@ -36,6 +36,7 @@ import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL; import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkTemplate.buildTemplateMobileWildcard; import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
import static android.net.NetworkTemplate.buildTemplateWifiWildcard; import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
import static android.net.TrafficStats.KB_IN_BYTES;
import static android.net.TrafficStats.MB_IN_BYTES; import static android.net.TrafficStats.MB_IN_BYTES;
import static android.provider.Settings.Secure.NETSTATS_DEV_BUCKET_DURATION; import static android.provider.Settings.Secure.NETSTATS_DEV_BUCKET_DURATION;
import static android.provider.Settings.Secure.NETSTATS_DEV_DELETE_AGE; import static android.provider.Settings.Secure.NETSTATS_DEV_DELETE_AGE;
@@ -49,6 +50,10 @@ import static android.provider.Settings.Secure.NETSTATS_UID_BUCKET_DURATION;
import static android.provider.Settings.Secure.NETSTATS_UID_DELETE_AGE; import static android.provider.Settings.Secure.NETSTATS_UID_DELETE_AGE;
import static android.provider.Settings.Secure.NETSTATS_UID_PERSIST_BYTES; import static android.provider.Settings.Secure.NETSTATS_UID_PERSIST_BYTES;
import static android.provider.Settings.Secure.NETSTATS_UID_ROTATE_AGE; import static android.provider.Settings.Secure.NETSTATS_UID_ROTATE_AGE;
import static android.provider.Settings.Secure.NETSTATS_UID_TAG_BUCKET_DURATION;
import static android.provider.Settings.Secure.NETSTATS_UID_TAG_DELETE_AGE;
import static android.provider.Settings.Secure.NETSTATS_UID_TAG_PERSIST_BYTES;
import static android.provider.Settings.Secure.NETSTATS_UID_TAG_ROTATE_AGE;
import static android.telephony.PhoneStateListener.LISTEN_DATA_CONNECTION_STATE; import static android.telephony.PhoneStateListener.LISTEN_DATA_CONNECTION_STATE;
import static android.telephony.PhoneStateListener.LISTEN_NONE; import static android.telephony.PhoneStateListener.LISTEN_NONE;
import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.text.format.DateUtils.DAY_IN_MILLIS;
@@ -94,10 +99,12 @@ import android.os.PowerManager;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.SystemClock; import android.os.SystemClock;
import android.provider.Settings; import android.provider.Settings;
import android.provider.Settings.Secure;
import android.telephony.PhoneStateListener; import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.util.EventLog; import android.util.EventLog;
import android.util.Log; import android.util.Log;
import android.util.MathUtils;
import android.util.NtpTrustedTime; import android.util.NtpTrustedTime;
import android.util.Slog; import android.util.Slog;
import android.util.SparseIntArray; import android.util.SparseIntArray;
@@ -169,19 +176,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
public interface NetworkStatsSettings { public interface NetworkStatsSettings {
public long getPollInterval(); public long getPollInterval();
public long getTimeCacheMaxAge(); public long getTimeCacheMaxAge();
public long getGlobalAlertBytes();
public boolean getSampleEnabled(); public boolean getSampleEnabled();
public static class Config { public static class Config {
public final long bucketDuration; public final long bucketDuration;
public final long persistBytes;
public final long rotateAgeMillis; public final long rotateAgeMillis;
public final long deleteAgeMillis; public final long deleteAgeMillis;
public Config(long bucketDuration, long persistBytes, long rotateAgeMillis, public Config(long bucketDuration, long rotateAgeMillis, long deleteAgeMillis) {
long deleteAgeMillis) {
this.bucketDuration = bucketDuration; this.bucketDuration = bucketDuration;
this.persistBytes = persistBytes;
this.rotateAgeMillis = rotateAgeMillis; this.rotateAgeMillis = rotateAgeMillis;
this.deleteAgeMillis = deleteAgeMillis; this.deleteAgeMillis = deleteAgeMillis;
} }
@@ -191,6 +194,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
public Config getXtConfig(); public Config getXtConfig();
public Config getUidConfig(); public Config getUidConfig();
public Config getUidTagConfig(); public Config getUidTagConfig();
public long getGlobalAlertBytes(long def);
public long getDevPersistBytes(long def);
public long getXtPersistBytes(long def);
public long getUidPersistBytes(long def);
public long getUidTagPersistBytes(long def);
} }
private final Object mStatsLock = new Object(); private final Object mStatsLock = new Object();
@@ -223,6 +232,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private final Handler mHandler; private final Handler mHandler;
private boolean mSystemReady; private boolean mSystemReady;
private long mPersistThreshold = 2 * MB_IN_BYTES;
private long mGlobalAlertBytes;
public NetworkStatsService( public NetworkStatsService(
Context context, INetworkManagementService networkManager, IAlarmManager alarmManager) { Context context, INetworkManagementService networkManager, IAlarmManager alarmManager) {
@@ -275,6 +286,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false); mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false);
mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true); mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true);
updatePersistThresholds();
synchronized (mStatsLock) { synchronized (mStatsLock) {
// upgrade any legacy stats, migrating them to rotated files // upgrade any legacy stats, migrating them to rotated files
maybeUpgradeLegacyStatsLocked(); maybeUpgradeLegacyStatsLocked();
@@ -325,10 +338,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private NetworkStatsRecorder buildRecorder( private NetworkStatsRecorder buildRecorder(
String prefix, NetworkStatsSettings.Config config, boolean includeTags) { String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
return new NetworkStatsRecorder( return new NetworkStatsRecorder(new FileRotator(
new FileRotator(mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis), mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
mNonMonotonicObserver, prefix, config.bucketDuration, config.persistBytes, mNonMonotonicObserver, prefix, config.bucketDuration, includeTags);
includeTags);
} }
private void shutdownLocked() { private void shutdownLocked() {
@@ -414,8 +426,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
*/ */
private void registerGlobalAlert() { private void registerGlobalAlert() {
try { try {
final long alertBytes = mSettings.getGlobalAlertBytes(); mNetworkManager.setGlobalAlert(mGlobalAlertBytes);
mNetworkManager.setGlobalAlert(alertBytes);
} catch (IllegalStateException e) { } catch (IllegalStateException e) {
Slog.w(TAG, "problem registering for global alert: " + e); Slog.w(TAG, "problem registering for global alert: " + e);
} catch (RemoteException e) { } catch (RemoteException e) {
@@ -437,14 +448,18 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private NetworkStatsCollection getUidComplete() { private NetworkStatsCollection getUidComplete() {
if (mUidComplete == null) { if (mUidComplete == null) {
mUidComplete = mUidRecorder.getOrLoadCompleteLocked(); synchronized (mStatsLock) {
mUidComplete = mUidRecorder.getOrLoadCompleteLocked();
}
} }
return mUidComplete; return mUidComplete;
} }
private NetworkStatsCollection getUidTagComplete() { private NetworkStatsCollection getUidTagComplete() {
if (mUidTagComplete == null) { if (mUidTagComplete == null) {
mUidTagComplete = mUidTagRecorder.getOrLoadCompleteLocked(); synchronized (mStatsLock) {
mUidTagComplete = mUidTagRecorder.getOrLoadCompleteLocked();
}
} }
return mUidTagComplete; return mUidTagComplete;
} }
@@ -584,6 +599,45 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
} }
} }
@Override
public void advisePersistThreshold(long thresholdBytes) {
mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG);
assertBandwidthControlEnabled();
// clamp threshold into safe range
mPersistThreshold = MathUtils.constrain(thresholdBytes, 128 * KB_IN_BYTES, 2 * MB_IN_BYTES);
updatePersistThresholds();
if (LOGV) {
Slog.v(TAG, "advisePersistThreshold() given " + thresholdBytes + ", clamped to "
+ mPersistThreshold);
}
// persist if beyond new thresholds
final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
: System.currentTimeMillis();
mDevRecorder.maybePersistLocked(currentTime);
mXtRecorder.maybePersistLocked(currentTime);
mUidRecorder.maybePersistLocked(currentTime);
mUidTagRecorder.maybePersistLocked(currentTime);
// re-arm global alert
registerGlobalAlert();
}
/**
* Update {@link NetworkStatsRecorder} and {@link #mGlobalAlertBytes} to
* reflect current {@link #mPersistThreshold} value. Always defers to
* {@link Secure} values when defined.
*/
private void updatePersistThresholds() {
mDevRecorder.setPersistThreshold(mSettings.getDevPersistBytes(mPersistThreshold));
mXtRecorder.setPersistThreshold(mSettings.getXtPersistBytes(mPersistThreshold));
mUidRecorder.setPersistThreshold(mSettings.getUidPersistBytes(mPersistThreshold));
mUidTagRecorder.setPersistThreshold(mSettings.getUidTagPersistBytes(mPersistThreshold));
mGlobalAlertBytes = mSettings.getGlobalAlertBytes(mPersistThreshold);
}
/** /**
* Receiver that watches for {@link IConnectivityManager} to claim network * Receiver that watches for {@link IConnectivityManager} to claim network
* interfaces. Used to associate {@link TelephonyManager#getSubscriberId()} * interfaces. Used to associate {@link TelephonyManager#getSubscriberId()}
@@ -1122,41 +1176,50 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
return getSecureLong(NETSTATS_TIME_CACHE_MAX_AGE, DAY_IN_MILLIS); return getSecureLong(NETSTATS_TIME_CACHE_MAX_AGE, DAY_IN_MILLIS);
} }
@Override @Override
public long getGlobalAlertBytes() { public long getGlobalAlertBytes(long def) {
return getSecureLong(NETSTATS_GLOBAL_ALERT_BYTES, 2 * MB_IN_BYTES); return getSecureLong(NETSTATS_GLOBAL_ALERT_BYTES, def);
} }
@Override @Override
public boolean getSampleEnabled() { public boolean getSampleEnabled() {
return getSecureBoolean(NETSTATS_SAMPLE_ENABLED, true); return getSecureBoolean(NETSTATS_SAMPLE_ENABLED, true);
} }
@Override @Override
public Config getDevConfig() { public Config getDevConfig() {
return new Config(getSecureLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS), return new Config(getSecureLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
getSecureLong(NETSTATS_DEV_PERSIST_BYTES, 2 * MB_IN_BYTES),
getSecureLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS), getSecureLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
getSecureLong(NETSTATS_DEV_DELETE_AGE, 90 * DAY_IN_MILLIS)); getSecureLong(NETSTATS_DEV_DELETE_AGE, 90 * DAY_IN_MILLIS));
} }
@Override @Override
public Config getXtConfig() { public Config getXtConfig() {
return getDevConfig(); return getDevConfig();
} }
@Override @Override
public Config getUidConfig() { public Config getUidConfig() {
return new Config(getSecureLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS), return new Config(getSecureLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
getSecureLong(NETSTATS_UID_PERSIST_BYTES, 2 * MB_IN_BYTES),
getSecureLong(NETSTATS_UID_ROTATE_AGE, 15 * DAY_IN_MILLIS), getSecureLong(NETSTATS_UID_ROTATE_AGE, 15 * DAY_IN_MILLIS),
getSecureLong(NETSTATS_UID_DELETE_AGE, 90 * DAY_IN_MILLIS)); getSecureLong(NETSTATS_UID_DELETE_AGE, 90 * DAY_IN_MILLIS));
} }
@Override @Override
public Config getUidTagConfig() { public Config getUidTagConfig() {
return new Config(getSecureLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS), return new Config(getSecureLong(NETSTATS_UID_TAG_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
getSecureLong(NETSTATS_UID_PERSIST_BYTES, 2 * MB_IN_BYTES), getSecureLong(NETSTATS_UID_TAG_ROTATE_AGE, 5 * DAY_IN_MILLIS),
getSecureLong(NETSTATS_UID_ROTATE_AGE, 5 * DAY_IN_MILLIS), getSecureLong(NETSTATS_UID_TAG_DELETE_AGE, 15 * DAY_IN_MILLIS));
getSecureLong(NETSTATS_UID_DELETE_AGE, 15 * DAY_IN_MILLIS)); }
@Override
public long getDevPersistBytes(long def) {
return getSecureLong(NETSTATS_DEV_PERSIST_BYTES, def);
}
@Override
public long getXtPersistBytes(long def) {
return getDevPersistBytes(def);
}
@Override
public long getUidPersistBytes(long def) {
return getSecureLong(NETSTATS_UID_PERSIST_BYTES, def);
}
@Override
public long getUidTagPersistBytes(long def) {
return getSecureLong(NETSTATS_UID_TAG_PERSIST_BYTES, def);
} }
} }
} }