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

Commit 50fd36d7 authored by Ashish Sharma's avatar Ashish Sharma Committed by Jeff Sharkey
Browse files

Push interface quota rules from NetworkPolicyManager to kernel.

Change-Id: Id2b758f561820b44839f69bf5fbd676cae771fe3
parent b8e52574
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
@@ -921,6 +921,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);
    }
}