Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 350083e3 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Migrate bandwidth control to NMS, omit history.

Both stats and policy make NMS calls that depend on bandwidth control
being enabled, so move enable/disable into NMS and drop calls when
disabled.  This avoids throwing heavy ISE exceptions when disabled.

Only include recent data when writing NetworkStatsHistory as part of
dumpsys call.  Introduce manual poll event for Settings UI.

Bug: 4982115, 4770435, 4515856
Change-Id: I257820b057af2f0f99c736fb4f61e55b9fdc3e66
parent 428e8438
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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();

}
+10 −3
Original line number Diff line number Diff line
@@ -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();
    }

+0 −2
Original line number Diff line number Diff line
@@ -241,6 +241,4 @@ interface INetworkManagementService
     */
    int getInterfaceTxThrottle(String iface);

    void setBandwidthControlEnabled(boolean enabled);

}
+42 −9
Original line number Diff line number Diff line
@@ -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}.
     */
+2 −0
Original line number Diff line number Diff line
@@ -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();
Loading