diff options
8 files changed, 75 insertions, 46 deletions
diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl index ae9aa05..0548250 100644 --- a/core/java/android/net/INetworkStatsService.aidl +++ b/core/java/android/net/INetworkStatsService.aidl @@ -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(); + } diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java index ff6e220..dd2945c 100644 --- a/core/java/android/net/NetworkStatsHistory.java +++ b/core/java/android/net/NetworkStatsHistory.java @@ -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(); } diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl index c9b6121..fcf4796 100644 --- a/core/java/android/os/INetworkManagementService.aidl +++ b/core/java/android/os/INetworkManagementService.aidl @@ -241,6 +241,4 @@ interface INetworkManagementService */ int getInterfaceTxThrottle(String iface); - void setBandwidthControlEnabled(boolean enabled); - } diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java index adc6570..1c150f8 100644 --- a/services/java/com/android/server/NetworkManagementService.java +++ b/services/java/com/android/server/NetworkManagementService.java @@ -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}. */ diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index dbfd145..8c7e279 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -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(); diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java index 1f2ec2c..2a17cbe 100644 --- a/services/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java @@ -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); diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java index 7610a11..b4bd176 100644 --- a/services/java/com/android/server/net/NetworkStatsService.java +++ b/services/java/com/android/server/net/NetworkStatsService.java @@ -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); } diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java index 903f2b0..f2c28bb 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java @@ -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(); |