Merge "Migrate bandwidth control to NMS, omit history."

This commit is contained in:
Jeff Sharkey
2011-06-30 23:09:51 -07:00
committed by Android (Google) Code Review
8 changed files with 75 additions and 46 deletions

View File

@@ -33,4 +33,7 @@ interface INetworkStatsService {
/** Return usage summary per UID for traffic that matches template. */
NetworkStats getSummaryForAllUid(in NetworkTemplate template, long start, long end, boolean includeTags);
/** Force update of statistics. */
void forceUpdate();
}

View File

@@ -279,10 +279,17 @@ public class NetworkStatsHistory implements Parcelable {
return (long) (start + (r.nextFloat() * (end - start)));
}
public void dump(String prefix, PrintWriter pw) {
public void dump(String prefix, PrintWriter pw, boolean fullHistory) {
pw.print(prefix);
pw.print("NetworkStatsHistory: bucketDuration="); pw.println(bucketDuration);
for (int i = 0; i < bucketCount; i++) {
final int start = fullHistory ? 0 : Math.max(0, bucketCount - 32);
if (start > 0) {
pw.print(prefix);
pw.print(" (omitting "); pw.print(start); pw.println(" buckets)");
}
for (int i = start; i < bucketCount; i++) {
pw.print(prefix);
pw.print(" bucketStart="); pw.print(bucketStart[i]);
pw.print(" rx="); pw.print(rx[i]);
@@ -293,7 +300,7 @@ public class NetworkStatsHistory implements Parcelable {
@Override
public String toString() {
final CharArrayWriter writer = new CharArrayWriter();
dump("", new PrintWriter(writer));
dump("", new PrintWriter(writer), false);
return writer.toString();
}

View File

@@ -241,6 +241,4 @@ interface INetworkManagementService
*/
int getInterfaceTxThrottle(String iface);
void setBandwidthControlEnabled(boolean enabled);
}

View File

@@ -16,10 +16,11 @@
package com.android.server;
import static android.Manifest.permission.MANAGE_NETWORK_POLICY;
import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
import static android.Manifest.permission.MANAGE_NETWORK_POLICY;
import static android.provider.Settings.Secure.NETSTATS_ENABLED;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -35,6 +36,7 @@ import android.os.Binder;
import android.os.INetworkManagementService;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.provider.Settings;
import android.util.Log;
import android.util.Slog;
import android.util.SparseBooleanArray;
@@ -123,6 +125,8 @@ class NetworkManagementService extends INetworkManagementService.Stub {
/** Set of UIDs with active reject rules. */
private SparseBooleanArray mUidRejectOnQuota = new SparseBooleanArray();
private boolean mBandwidthControlEnabled;
/**
* Constructs a new NetworkManagementService instance
*
@@ -161,6 +165,29 @@ class NetworkManagementService extends INetworkManagementService.Stub {
return new NetworkManagementService(context, procRoot);
}
public void systemReady() {
// only enable bandwidth control when support exists, and requested by
// system setting.
// TODO: eventually migrate to be always enabled
final boolean hasKernelSupport = new File("/proc/net/xt_qtaguid/ctrl").exists();
final boolean shouldEnable =
Settings.Secure.getInt(mContext.getContentResolver(), NETSTATS_ENABLED, 0) != 0;
mBandwidthControlEnabled = false;
if (hasKernelSupport && shouldEnable) {
Slog.d(TAG, "enabling bandwidth control");
try {
mConnector.doCommand("bandwidth enable");
mBandwidthControlEnabled = true;
} catch (NativeDaemonConnectorException e) {
Slog.e(TAG, "problem enabling bandwidth controls", e);
}
} else {
Slog.d(TAG, "not enabling bandwidth control");
}
}
public void registerObserver(INetworkManagementEventObserver obs) {
Slog.d(TAG, "Registering observer");
mObservers.add(obs);
@@ -919,7 +946,7 @@ class NetworkManagementService extends INetworkManagementService.Stub {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
if (mProcStatsNetfilter.exists()) {
if (mBandwidthControlEnabled) {
return getNetworkStatsDetailNetfilter(UID_ALL);
} else {
return getNetworkStatsDetailUidstat(UID_ALL);
@@ -930,6 +957,10 @@ class NetworkManagementService extends INetworkManagementService.Stub {
public void setInterfaceQuota(String iface, long quota) {
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
// silently discard when control disabled
// TODO: eventually migrate to be always enabled
if (!mBandwidthControlEnabled) return;
synchronized (mInterfaceQuota) {
if (mInterfaceQuota.contains(iface)) {
// TODO: eventually consider throwing
@@ -953,6 +984,10 @@ class NetworkManagementService extends INetworkManagementService.Stub {
public void removeInterfaceQuota(String iface) {
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
// silently discard when control disabled
// TODO: eventually migrate to be always enabled
if (!mBandwidthControlEnabled) return;
synchronized (mInterfaceQuota) {
if (!mInterfaceQuota.contains(iface)) {
// TODO: eventually consider throwing
@@ -976,6 +1011,10 @@ class NetworkManagementService extends INetworkManagementService.Stub {
public void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) {
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
// silently discard when control disabled
// TODO: eventually migrate to be always enabled
if (!mBandwidthControlEnabled) return;
synchronized (mUidRejectOnQuota) {
final boolean oldRejectOnQuota = mUidRejectOnQuota.get(uid, false);
if (oldRejectOnQuota == rejectOnQuotaInterfaces) {
@@ -1011,7 +1050,7 @@ class NetworkManagementService extends INetworkManagementService.Stub {
android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
}
if (mProcStatsNetfilter.exists()) {
if (mBandwidthControlEnabled) {
return getNetworkStatsDetailNetfilter(uid);
} else {
return getNetworkStatsDetailUidstat(uid);
@@ -1151,12 +1190,6 @@ class NetworkManagementService extends INetworkManagementService.Stub {
return getInterfaceThrottle(iface, false);
}
@Override
public void setBandwidthControlEnabled(boolean enabled) {
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
mConnector.doCommand(String.format("bandwidth %s", (enabled ? "enable" : "disable")));
}
/**
* Split given line into {@link ArrayList}.
*/

View File

@@ -523,6 +523,7 @@ class ServerThread extends Thread {
// These are needed to propagate to the runnable below.
final Context contextF = context;
final BatteryService batteryF = battery;
final NetworkManagementService networkManagementF = networkManagement;
final NetworkStatsService networkStatsF = networkStats;
final NetworkPolicyManagerService networkPolicyF = networkPolicy;
final ConnectivityService connectivityF = connectivity;
@@ -550,6 +551,7 @@ class ServerThread extends Thread {
startSystemUi(contextF);
if (batteryF != null) batteryF.systemReady();
if (networkManagementF != null) networkManagementF.systemReady();
if (networkStatsF != null) networkStatsF.systemReady();
if (networkPolicyF != null) networkPolicyF.systemReady();
if (connectivityF != null) connectivityF.systemReady();

View File

@@ -1044,8 +1044,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// TODO: only dispatch when rules actually change
// record rule locally to dispatch to new listeners
mUidRules.put(uid, uidRules);
if (uidRules == RULE_ALLOW_ALL) {
mUidRules.delete(uid);
} else {
mUidRules.put(uid, uidRules);
}
final boolean rejectMetered = (uidRules & RULE_REJECT_METERED) != 0;
setUidNetworkRules(uid, rejectMetered);

View File

@@ -134,7 +134,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
* Settings that can be changed externally.
*/
public interface NetworkStatsSettings {
public boolean getEnabled();
public long getPollInterval();
public long getPersistThreshold();
public long getNetworkBucketDuration();
@@ -207,20 +206,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
public void systemReady() {
if (mSettings.getEnabled()) {
try {
// enable low-level bandwidth stats and control
// TODO: consider shipping with this enabled by default
mNetworkManager.setBandwidthControlEnabled(true);
} catch (RemoteException e) {
Slog.e(TAG, "problem talking to netd while enabling bandwidth controls", e);
} catch (NativeDaemonConnectorException ndce) {
Slog.e(TAG, "problem enabling bandwidth controls", ndce);
}
} else {
Slog.w(TAG, "detailed network stats disabled");
}
synchronized (mStatsLock) {
// read historical network stats from disk, since policy service
// might need them right away. we delay loading detailed UID stats
@@ -389,6 +374,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
}
@Override
public void forceUpdate() {
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
synchronized (mStatsLock) {
performPollLocked(true, false);
}
}
/**
* Receiver that watches for {@link IConnectivityManager} to claim network
* interfaces. Used to associate {@link TelephonyManager#getSubscriberId()}
@@ -905,6 +899,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
argSet.add(arg);
}
final boolean fullHistory = argSet.contains("full");
synchronized (mStatsLock) {
// TODO: remove this testing code, since it corrupts stats
if (argSet.contains("generate")) {
@@ -930,7 +926,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
for (NetworkIdentitySet ident : mNetworkStats.keySet()) {
final NetworkStatsHistory history = mNetworkStats.get(ident);
pw.print(" ident="); pw.println(ident.toString());
history.dump(" ", pw);
history.dump(" ", pw, fullHistory);
}
if (argSet.contains("detail")) {
@@ -950,7 +946,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final NetworkStatsHistory history = uidStats.valueAt(i);
pw.print(" UID="); pw.print(uid);
pw.print(" tag="); pw.println(tag);
history.dump(" ", pw);
history.dump(" ", pw, fullHistory);
}
}
}
@@ -1058,15 +1054,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
return Settings.Secure.getLong(mResolver, name, def);
}
public boolean getEnabled() {
if (!new File("/proc/net/xt_qtaguid/ctrl").exists()) {
Slog.w(TAG, "kernel does not support bandwidth control");
return false;
}
// TODO: once things stabilize, enable by default.
// For now: ./vendor/google/tools/override-gservices secure:netstats_enabled=1
return Settings.Secure.getInt(mResolver, NETSTATS_ENABLED, 0) != 0;
}
public long getPollInterval() {
return getSecureLong(NETSTATS_POLL_INTERVAL, 15 * MINUTE_IN_MILLIS);
}

View File

@@ -610,9 +610,6 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
mAlarmManager.setInexactRepeating(
eq(AlarmManager.ELAPSED_REALTIME), anyLong(), anyLong(), isA(PendingIntent.class));
expectLastCall().atLeastOnce();
mNetManager.setBandwidthControlEnabled(true);
expectLastCall().atLeastOnce();
}
private void expectNetworkState(NetworkState... state) throws Exception {
@@ -633,7 +630,6 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
private void expectSettings(long persistThreshold, long bucketDuration, long maxHistory)
throws Exception {
expect(mSettings.getEnabled()).andReturn(true).anyTimes();
expect(mSettings.getPollInterval()).andReturn(HOUR_IN_MILLIS).anyTimes();
expect(mSettings.getPersistThreshold()).andReturn(persistThreshold).anyTimes();
expect(mSettings.getNetworkBucketDuration()).andReturn(bucketDuration).anyTimes();