Merge "Migrate bandwidth control to NMS, omit history."
This commit is contained in:
@@ -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();
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -241,6 +241,4 @@ interface INetworkManagementService
|
||||
*/
|
||||
int getInterfaceTxThrottle(String iface);
|
||||
|
||||
void setBandwidthControlEnabled(boolean enabled);
|
||||
|
||||
}
|
||||
|
||||
@@ -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}.
|
||||
*/
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user