Push interface quota rules from NetworkPolicyManager to kernel.
Change-Id: Id2b758f561820b44839f69bf5fbd676cae771fe3
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 630aaf9..634a3f2 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -921,6 +921,38 @@
}
@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 cd68c68..dbfd145 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -283,7 +283,8 @@
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 12d3ed8..8a93f43 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.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 @@
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 @@
// 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 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 @@
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 @@
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 @@
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();