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

Commit afb60c36 authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge "Push interface quota rules from NetworkPolicyManager to kernel."

parents 2d700947 50fd36d7
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -209,6 +209,16 @@ interface INetworkManagementService
     */
    NetworkStats getNetworkStatsUidDetail(int uid);

    /**
     * Set an overall quota for a group of interfaces.
     */
    void setInterfaceQuota(in String[] iface, long quota);

    /**
     * Control network activity of a UID over interfaces with a quota limit.
     */
    void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces);

    /**
     * Configures bandwidth throttling on an interface.
     */
+32 −0
Original line number Diff line number Diff line
@@ -919,6 +919,38 @@ class NetworkManagementService extends INetworkManagementService.Stub {
    }

    @Override
    public void setInterfaceQuota(String[] iface, long quota)
            throws IllegalStateException {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.MANAGE_NETWORK_POLICY, "NetworkManagementService");
        try {
            // TODO: Add support for clubbing together multiple interfaces under
            // one quota. Will need support from the kernel and
            // BandwidthController to do this.
            mConnector.doCommand(
                    String.format("bandwidth setquota %s %d", iface[0], quota));
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException(
                    "Error communicating to native daemon to set Interface quota",
                    e);
        }
    }

    @Override
    public void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces)
            throws IllegalStateException {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.MANAGE_NETWORK_POLICY, "NetworkManagementService");
        try {
            // TODO: Connect with BandwidthController
            // mConnector.doCommand("");
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException(
                    "Error communicating to native daemon to set Interface quota",
                    e);
        }
    }

    public NetworkStats getNetworkStatsUidDetail(int uid) {
        if (Binder.getCallingUid() != uid) {
            mContext.enforceCallingOrSelfPermission(
+2 −1
Original line number Diff line number Diff line
@@ -283,7 +283,8 @@ class ServerThread extends Thread {
            try {
                Slog.i(TAG, "NetworkPolicy Service");
                networkPolicy = new NetworkPolicyManagerService(
                        context, ActivityManagerService.self(), power, networkStats);
                        context, ActivityManagerService.self(), power,
                        networkStats, networkManagement);
                ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);
            } catch (Throwable e) {
                Slog.e(TAG, "Failure starting NetworkPolicy Service", e);
+44 −6
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ import android.net.NetworkTemplate;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.INetworkManagementService;
import android.os.IPowerManager;
import android.os.Message;
import android.os.RemoteCallbackList;
@@ -156,6 +157,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
    private final IActivityManager mActivityManager;
    private final IPowerManager mPowerManager;
    private final INetworkStatsService mNetworkStats;
    private final INetworkManagementService mNetworkManagement;
    private final TrustedTime mTime;

    private IConnectivityManager mConnManager;
@@ -193,9 +195,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
    // rules enforced, such as system, phone, and radio UIDs.

    public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
            IPowerManager powerManager, INetworkStatsService networkStats) {
            IPowerManager powerManager, INetworkStatsService networkStats,
            INetworkManagementService networkManagement) {
        // TODO: move to using cached NtpTrustedTime
        this(context, activityManager, powerManager, networkStats, new NtpTrustedTime(),
        this(context, activityManager, powerManager, networkStats,
                networkManagement, new NtpTrustedTime(),
                getSystemDir());
    }

@@ -204,12 +208,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
    }

    public NetworkPolicyManagerService(Context context, IActivityManager activityManager,
            IPowerManager powerManager, INetworkStatsService networkStats, TrustedTime time,
            File systemDir) {
            IPowerManager powerManager, INetworkStatsService networkStats,
            INetworkManagementService networkManagement,
            TrustedTime time, File systemDir) {
        mContext = checkNotNull(context, "missing context");
        mActivityManager = checkNotNull(activityManager, "missing activityManager");
        mPowerManager = checkNotNull(powerManager, "missing powerManager");
        mNetworkStats = checkNotNull(networkStats, "missing networkStats");
        mNetworkManagement = checkNotNull(networkManagement, "missing networkManagementService");
        mTime = checkNotNull(time, "missing TrustedTime");

        mHandlerThread = new HandlerThread(TAG);
@@ -589,7 +595,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
            if (policy.limitBytes != NetworkPolicy.LIMIT_DISABLED) {
                // remaining "quota" is based on usage in current cycle
                final long quota = Math.max(0, policy.limitBytes - total);
                //kernelSetIfacesQuota(ifaces, quota);
                if (LOGD) {
                    Slog.d(TAG, "Applying quota rules for ifaces=" + Arrays.toString(ifaces)
                            + " LIMIT=" + policy.limitBytes + "  TOTAL="
                            + total + "  QUOTA=" + quota);
                }

                setQuotaOnIfaceList(ifaces, quota);

                for (String iface : ifaces) {
                    mMeteredIfaces.add(iface);
@@ -601,6 +613,32 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
        mHandler.obtainMessage(MSG_METERED_IFACES_CHANGED, meteredIfaces).sendToTarget();
    }

    private void setQuotaOnIfaceList(String[] ifaces, long quota) {
        try {
            mNetworkManagement.setInterfaceQuota(ifaces, quota);
        } catch (IllegalStateException e) {
            Slog.e(TAG, "IllegalStateException in setQuotaOnIfaceList " + e);
        } catch (RemoteException e) {
            Slog.e(TAG, "Remote Exception in setQuotaOnIfaceList " + e);
        }
    }

    private void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) {
        // TODO: connect over to NMS
        // ndc bandwidth app <uid> naughty
        try {
            if (LOGD) {
                Slog.d(TAG, "setUidNetworkRules() with uid=" + uid
                        + ", rejectOnQuotaInterfaces=" + rejectOnQuotaInterfaces);
            }
            mNetworkManagement.setUidNetworkRules(uid, rejectOnQuotaInterfaces);
        } catch (IllegalStateException e) {
            Slog.e(TAG, "IllegalStateException in setUidNetworkRules " + e);
        } catch (RemoteException e) {
            Slog.e(TAG, "Remote Exception in setUidNetworkRules " + e);
        }
    }

    /**
     * Once any {@link #mNetworkPolicy} are loaded from disk, ensure that we
     * have at least a default mobile policy defined.
@@ -955,7 +993,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
        mUidRules.put(uid, uidRules);

        final boolean rejectMetered = (uidRules & RULE_REJECT_METERED) != 0;
        //kernelSetUidRejectPaid(uid, rejectPaid);
        setUidNetworkRules(uid, rejectMetered);

        // dispatch changed rule to existing listeners
        mHandler.obtainMessage(MSG_RULES_CHANGED, uid, uidRules).sendToTarget();
+11 −7
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ import android.net.NetworkState;
import android.net.NetworkStats;
import android.net.NetworkTemplate;
import android.os.Binder;
import android.os.INetworkManagementService;
import android.os.IPowerManager;
import android.test.AndroidTestCase;
import android.test.mock.MockPackageManager;
@@ -95,6 +96,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
    private IActivityManager mActivityManager;
    private IPowerManager mPowerManager;
    private INetworkStatsService mStatsService;
    private INetworkManagementService mNetworkManagement;
    private INetworkPolicyListener mPolicyListener;
    private TrustedTime mTime;
    private IConnectivityManager mConnManager;
@@ -150,13 +152,15 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
        mActivityManager = createMock(IActivityManager.class);
        mPowerManager = createMock(IPowerManager.class);
        mStatsService = createMock(INetworkStatsService.class);
        mNetworkManagement = createMock(INetworkManagementService.class);
        mPolicyListener = createMock(INetworkPolicyListener.class);
        mTime = createMock(TrustedTime.class);
        mConnManager = createMock(IConnectivityManager.class);
        mNotifManager = createMock(INotificationManager.class);

        mService = new NetworkPolicyManagerService(
                mServiceContext, mActivityManager, mPowerManager, mStatsService, mTime, mPolicyDir);
                mServiceContext, mActivityManager, mPowerManager, mStatsService,
                mNetworkManagement, mTime, mPolicyDir);
        mService.bindConnectivityManager(mConnManager);
        mService.bindNotificationManager(mNotifManager);

@@ -526,14 +530,14 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
    }

    private void replay() {
        EasyMock.replay(mActivityManager, mPowerManager, mStatsService, mPolicyListener, mTime,
                mConnManager, mNotifManager);
        EasyMock.replay(mActivityManager, mPowerManager, mStatsService, mPolicyListener,
                mNetworkManagement, mTime, mConnManager, mNotifManager);
    }

    private void verifyAndReset() {
        EasyMock.verify(mActivityManager, mPowerManager, mStatsService, mPolicyListener, mTime,
                mConnManager, mNotifManager);
        EasyMock.reset(mActivityManager, mPowerManager, mStatsService, mPolicyListener, mTime,
                mConnManager, mNotifManager);
        EasyMock.verify(mActivityManager, mPowerManager, mStatsService, mPolicyListener,
                mNetworkManagement, mTime, mConnManager, mNotifManager);
        EasyMock.reset(mActivityManager, mPowerManager, mStatsService, mPolicyListener,
                mNetworkManagement, mTime, mConnManager, mNotifManager);
    }
}