From 50fd36d7c38c40b087c8f3e3172478abe0c051d9 Mon Sep 17 00:00:00 2001 From: Ashish Sharma Date: Wed, 15 Jun 2011 19:34:53 -0700 Subject: [PATCH] Push interface quota rules from NetworkPolicyManager to kernel. Change-Id: Id2b758f561820b44839f69bf5fbd676cae771fe3 --- .../android/os/INetworkManagementService.aidl | 10 ++++ .../server/NetworkManagementService.java | 32 ++++++++++++ .../java/com/android/server/SystemServer.java | 3 +- .../net/NetworkPolicyManagerService.java | 50 ++++++++++++++++--- .../NetworkPolicyManagerServiceTest.java | 18 ++++--- 5 files changed, 99 insertions(+), 14 deletions(-) diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl index 1b09242d4c03e..047a265c6e76e 100644 --- a/core/java/android/os/INetworkManagementService.aidl +++ b/core/java/android/os/INetworkManagementService.aidl @@ -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. */ diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java index 630aaf9edafe3..634a3f207cdd1 100644 --- a/services/java/com/android/server/NetworkManagementService.java +++ b/services/java/com/android/server/NetworkManagementService.java @@ -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( diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index cd68c6854153b..dbfd145bc65f8 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -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); diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java index 12d3ed8b4dc5d..8a93f43db6001 100644 --- a/services/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java @@ -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 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(); diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java index 324e89600294f..af2e01ccf7473 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java @@ -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); } }