Merge "Refactored NetworkManagerService to support Data Saver." into nyc-dev
This commit is contained in:
@@ -293,7 +293,9 @@ interface INetworkManagementService
|
||||
/**
|
||||
* Control network activity of a UID over interfaces with a quota limit.
|
||||
*/
|
||||
void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces);
|
||||
void setUidMeteredNetworkBlacklist(int uid, boolean enable);
|
||||
void setUidMeteredNetworkWhitelist(int uid, boolean enable);
|
||||
boolean setDataSaverModeEnabled(boolean enable);
|
||||
|
||||
void setUidCleartextNetworkPolicy(int uid, int policy);
|
||||
|
||||
|
||||
@@ -209,9 +209,12 @@ public class NetworkManagementService extends INetworkManagementService.Stub
|
||||
/** Set of interfaces with active alerts. */
|
||||
@GuardedBy("mQuotaLock")
|
||||
private HashMap<String, Long> mActiveAlerts = Maps.newHashMap();
|
||||
/** Set of UIDs with active reject rules. */
|
||||
/** Set of UIDs blacklisted on metered networks. */
|
||||
@GuardedBy("mQuotaLock")
|
||||
private SparseBooleanArray mUidRejectOnQuota = new SparseBooleanArray();
|
||||
private SparseBooleanArray mUidRejectOnMetered = new SparseBooleanArray();
|
||||
/** Set of UIDs whitelisted on metered networks. */
|
||||
@GuardedBy("mQuotaLock")
|
||||
private SparseBooleanArray mUidAllowOnMetered = new SparseBooleanArray();
|
||||
/** Set of UIDs with cleartext penalties. */
|
||||
@GuardedBy("mQuotaLock")
|
||||
private SparseIntArray mUidCleartextPolicy = new SparseIntArray();
|
||||
@@ -240,6 +243,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub
|
||||
@GuardedBy("mQuotaLock")
|
||||
final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
|
||||
|
||||
@GuardedBy("mQuotaLock")
|
||||
private boolean mDataSaverMode;
|
||||
|
||||
private Object mIdleTimerLock = new Object();
|
||||
/** Set of interfaces with active idle timers. */
|
||||
private static class IdleTimerParams {
|
||||
@@ -583,6 +589,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub
|
||||
|
||||
// push any existing quota or UID rules
|
||||
synchronized (mQuotaLock) {
|
||||
|
||||
setDataSaverModeEnabled(mDataSaverMode);
|
||||
|
||||
int size = mActiveQuotas.size();
|
||||
if (size > 0) {
|
||||
if (DBG) Slog.d(TAG, "Pushing " + size + " active quota rules");
|
||||
@@ -603,13 +612,25 @@ public class NetworkManagementService extends INetworkManagementService.Stub
|
||||
}
|
||||
}
|
||||
|
||||
size = mUidRejectOnQuota.size();
|
||||
size = mUidRejectOnMetered.size();
|
||||
if (size > 0) {
|
||||
if (DBG) Slog.d(TAG, "Pushing " + size + " active UID rules");
|
||||
final SparseBooleanArray uidRejectOnQuota = mUidRejectOnQuota;
|
||||
mUidRejectOnQuota = new SparseBooleanArray();
|
||||
if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered whitelist rules");
|
||||
final SparseBooleanArray uidRejectOnQuota = mUidRejectOnMetered;
|
||||
mUidRejectOnMetered = new SparseBooleanArray();
|
||||
for (int i = 0; i < uidRejectOnQuota.size(); i++) {
|
||||
setUidNetworkRules(uidRejectOnQuota.keyAt(i), uidRejectOnQuota.valueAt(i));
|
||||
setUidMeteredNetworkBlacklist(uidRejectOnQuota.keyAt(i),
|
||||
uidRejectOnQuota.valueAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
size = mUidAllowOnMetered.size();
|
||||
if (size > 0) {
|
||||
if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered blacklist rules");
|
||||
final SparseBooleanArray uidAcceptOnQuota = mUidAllowOnMetered;
|
||||
mUidAllowOnMetered = new SparseBooleanArray();
|
||||
for (int i = 0; i < uidAcceptOnQuota.size(); i++) {
|
||||
setUidMeteredNetworkWhitelist(uidAcceptOnQuota.keyAt(i),
|
||||
uidAcceptOnQuota.valueAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -723,6 +744,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
|
||||
private class NetdCallbackReceiver implements INativeDaemonConnectorCallbacks {
|
||||
@Override
|
||||
public void onDaemonConnected() {
|
||||
Slog.i(TAG, "onDaemonConnected()");
|
||||
// event is dispatched from internal NDC thread, so we prepare the
|
||||
// daemon back on main thread.
|
||||
if (mConnectedSignal != null) {
|
||||
@@ -1683,28 +1705,30 @@ public class NetworkManagementService extends INetworkManagementService.Stub
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) {
|
||||
private void setUidOnMeteredNetworkList(SparseBooleanArray quotaList, int uid,
|
||||
boolean blacklist, boolean enable) {
|
||||
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
|
||||
|
||||
// silently discard when control disabled
|
||||
// TODO: eventually migrate to be always enabled
|
||||
if (!mBandwidthControlEnabled) return;
|
||||
|
||||
final String chain = blacklist ? "naughtyapps" : "niceapps";
|
||||
final String suffix = enable ? "add" : "remove";
|
||||
|
||||
synchronized (mQuotaLock) {
|
||||
final boolean oldRejectOnQuota = mUidRejectOnQuota.get(uid, false);
|
||||
if (oldRejectOnQuota == rejectOnQuotaInterfaces) {
|
||||
final boolean oldEnable = quotaList.get(uid, false);
|
||||
if (oldEnable == enable) {
|
||||
// TODO: eventually consider throwing
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mConnector.execute("bandwidth",
|
||||
rejectOnQuotaInterfaces ? "addnaughtyapps" : "removenaughtyapps", uid);
|
||||
if (rejectOnQuotaInterfaces) {
|
||||
mUidRejectOnQuota.put(uid, true);
|
||||
mConnector.execute("bandwidth", suffix + chain, uid);
|
||||
if (enable) {
|
||||
quotaList.put(uid, true);
|
||||
} else {
|
||||
mUidRejectOnQuota.delete(uid);
|
||||
quotaList.delete(uid);
|
||||
}
|
||||
} catch (NativeDaemonConnectorException e) {
|
||||
throw e.rethrowAsParcelableException();
|
||||
@@ -1712,6 +1736,39 @@ public class NetworkManagementService extends INetworkManagementService.Stub
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUidMeteredNetworkBlacklist(int uid, boolean enable) {
|
||||
setUidOnMeteredNetworkList(mUidRejectOnMetered, uid, true, enable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUidMeteredNetworkWhitelist(int uid, boolean enable) {
|
||||
setUidOnMeteredNetworkList(mUidAllowOnMetered, uid, false, enable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setDataSaverModeEnabled(boolean enable) {
|
||||
if (DBG) Log.d(TAG, "setDataSaverMode: " + enable);
|
||||
synchronized (mQuotaLock) {
|
||||
if (mDataSaverMode == enable) {
|
||||
Log.w(TAG, "setDataSaverMode(): already " + mDataSaverMode);
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
final boolean changed = mNetdService.bandwidthEnableDataSaver(enable);
|
||||
if (changed) {
|
||||
mDataSaverMode = enable;
|
||||
} else {
|
||||
Log.w(TAG, "setDataSaverMode(" + enable + "): netd command silently failed");
|
||||
}
|
||||
return changed;
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "setDataSaverMode(" + enable + "): netd command failed", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUidCleartextNetworkPolicy(int uid, int policy) {
|
||||
if (Binder.getCallingUid() != uid) {
|
||||
@@ -2206,29 +2263,22 @@ public class NetworkManagementService extends INetworkManagementService.Stub
|
||||
synchronized (mQuotaLock) {
|
||||
pw.print("Active quota ifaces: "); pw.println(mActiveQuotas.toString());
|
||||
pw.print("Active alert ifaces: "); pw.println(mActiveAlerts.toString());
|
||||
}
|
||||
|
||||
synchronized (mUidRejectOnQuota) {
|
||||
pw.print("UID reject on quota ifaces: [");
|
||||
final int size = mUidRejectOnQuota.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
pw.print(mUidRejectOnQuota.keyAt(i));
|
||||
if (i < size - 1) pw.print(",");
|
||||
}
|
||||
pw.println("]");
|
||||
pw.print("Data saver mode: "); pw.println(mDataSaverMode);
|
||||
dumpUidRuleOnQuotaLocked(pw, "blacklist", mUidRejectOnMetered);
|
||||
dumpUidRuleOnQuotaLocked(pw, "whitelist", mUidAllowOnMetered);
|
||||
}
|
||||
|
||||
synchronized (mUidFirewallRules) {
|
||||
dumpUidFirewallRule(pw, "", mUidFirewallRules);
|
||||
}
|
||||
|
||||
pw.println("UID firewall standby chain enabled: " +
|
||||
pw.print("UID firewall standby chain enabled: "); pw.println(
|
||||
mFirewallChainStates.get(FIREWALL_CHAIN_STANDBY));
|
||||
synchronized (mUidFirewallStandbyRules) {
|
||||
dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_STANDBY, mUidFirewallStandbyRules);
|
||||
}
|
||||
|
||||
pw.println("UID firewall dozable chain enabled: " +
|
||||
pw.print("UID firewall dozable chain enabled: "); pw.println(
|
||||
mFirewallChainStates.get(FIREWALL_CHAIN_DOZABLE));
|
||||
synchronized (mUidFirewallDozableRules) {
|
||||
dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_DOZABLE, mUidFirewallDozableRules);
|
||||
@@ -2252,6 +2302,29 @@ public class NetworkManagementService extends INetworkManagementService.Stub
|
||||
}
|
||||
|
||||
pw.print("Firewall enabled: "); pw.println(mFirewallEnabled);
|
||||
pw.print("Netd service status: " );
|
||||
if (mNetdService == null) {
|
||||
pw.println("disconnected");
|
||||
} else {
|
||||
try {
|
||||
final boolean alive = mNetdService.isAlive();
|
||||
pw.println(alive ? "alive": "dead");
|
||||
} catch (RemoteException e) {
|
||||
pw.println("unreachable");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void dumpUidRuleOnQuotaLocked(PrintWriter pw, String name, SparseBooleanArray list) {
|
||||
pw.print("UID bandwith control ");
|
||||
pw.print(name);
|
||||
pw.print(" rule: [");
|
||||
final int size = list.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
pw.print(list.keyAt(i));
|
||||
if (i < size - 1) pw.print(",");
|
||||
}
|
||||
pw.println("]");
|
||||
}
|
||||
|
||||
private void dumpUidFirewallRule(PrintWriter pw, String name, SparseIntArray rules) {
|
||||
|
||||
@@ -2803,7 +2803,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
|
||||
|
||||
private void setUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces) {
|
||||
try {
|
||||
mNetworkManager.setUidNetworkRules(uid, rejectOnQuotaInterfaces);
|
||||
mNetworkManager.setUidMeteredNetworkBlacklist(uid, rejectOnQuotaInterfaces);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.wtf(TAG, "problem setting uid rules", e);
|
||||
} catch (RemoteException e) {
|
||||
|
||||
@@ -313,7 +313,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
||||
public void testScreenChangesRules() throws Exception {
|
||||
Future<Void> future;
|
||||
|
||||
expectSetUidNetworkRules(UID_A, false);
|
||||
expectSetUidMeteredNetworkBlacklist(UID_A, false);
|
||||
expectSetUidForeground(UID_A, true);
|
||||
future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
|
||||
replay();
|
||||
@@ -322,7 +322,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
||||
verifyAndReset();
|
||||
|
||||
// push strict policy for foreground uid, verify ALLOW rule
|
||||
expectSetUidNetworkRules(UID_A, false);
|
||||
expectSetUidMeteredNetworkBlacklist(UID_A, false);
|
||||
expectSetUidForeground(UID_A, true);
|
||||
future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
|
||||
replay();
|
||||
@@ -332,7 +332,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
||||
|
||||
// now turn screen off and verify REJECT rule
|
||||
expect(mPowerManager.isInteractive()).andReturn(false).atLeastOnce();
|
||||
expectSetUidNetworkRules(UID_A, true);
|
||||
expectSetUidMeteredNetworkBlacklist(UID_A, true);
|
||||
expectSetUidForeground(UID_A, false);
|
||||
future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
|
||||
replay();
|
||||
@@ -342,7 +342,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
||||
|
||||
// and turn screen back on, verify ALLOW rule restored
|
||||
expect(mPowerManager.isInteractive()).andReturn(true).atLeastOnce();
|
||||
expectSetUidNetworkRules(UID_A, false);
|
||||
expectSetUidMeteredNetworkBlacklist(UID_A, false);
|
||||
expectSetUidForeground(UID_A, true);
|
||||
future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
|
||||
replay();
|
||||
@@ -354,7 +354,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
||||
public void testPolicyNone() throws Exception {
|
||||
Future<Void> future;
|
||||
|
||||
expectSetUidNetworkRules(UID_A, false);
|
||||
expectSetUidMeteredNetworkBlacklist(UID_A, false);
|
||||
expectSetUidForeground(UID_A, true);
|
||||
future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
|
||||
replay();
|
||||
@@ -363,7 +363,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
||||
verifyAndReset();
|
||||
|
||||
// POLICY_NONE should RULE_ALLOW in foreground
|
||||
expectSetUidNetworkRules(UID_A, false);
|
||||
expectSetUidMeteredNetworkBlacklist(UID_A, false);
|
||||
expectSetUidForeground(UID_A, true);
|
||||
future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
|
||||
replay();
|
||||
@@ -372,7 +372,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
||||
verifyAndReset();
|
||||
|
||||
// POLICY_NONE should RULE_ALLOW in background
|
||||
expectSetUidNetworkRules(UID_A, false);
|
||||
expectSetUidMeteredNetworkBlacklist(UID_A, false);
|
||||
expectSetUidForeground(UID_A, false);
|
||||
future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
|
||||
replay();
|
||||
@@ -385,7 +385,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
||||
Future<Void> future;
|
||||
|
||||
// POLICY_REJECT should RULE_ALLOW in background
|
||||
expectSetUidNetworkRules(UID_A, true);
|
||||
expectSetUidMeteredNetworkBlacklist(UID_A, true);
|
||||
expectSetUidForeground(UID_A, false);
|
||||
future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
|
||||
replay();
|
||||
@@ -394,7 +394,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
||||
verifyAndReset();
|
||||
|
||||
// POLICY_REJECT should RULE_ALLOW in foreground
|
||||
expectSetUidNetworkRules(UID_A, false);
|
||||
expectSetUidMeteredNetworkBlacklist(UID_A, false);
|
||||
expectSetUidForeground(UID_A, true);
|
||||
future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
|
||||
replay();
|
||||
@@ -403,7 +403,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
||||
verifyAndReset();
|
||||
|
||||
// POLICY_REJECT should RULE_REJECT in background
|
||||
expectSetUidNetworkRules(UID_A, true);
|
||||
expectSetUidMeteredNetworkBlacklist(UID_A, true);
|
||||
expectSetUidForeground(UID_A, false);
|
||||
future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
|
||||
replay();
|
||||
@@ -416,7 +416,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
||||
Future<Void> future;
|
||||
|
||||
// POLICY_NONE should have RULE_ALLOW in background
|
||||
expectSetUidNetworkRules(UID_A, false);
|
||||
expectSetUidMeteredNetworkBlacklist(UID_A, false);
|
||||
expectSetUidForeground(UID_A, false);
|
||||
future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
|
||||
replay();
|
||||
@@ -426,7 +426,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
||||
verifyAndReset();
|
||||
|
||||
// adding POLICY_REJECT should cause RULE_REJECT
|
||||
expectSetUidNetworkRules(UID_A, true);
|
||||
expectSetUidMeteredNetworkBlacklist(UID_A, true);
|
||||
expectSetUidForeground(UID_A, false);
|
||||
future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
|
||||
replay();
|
||||
@@ -435,7 +435,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
||||
verifyAndReset();
|
||||
|
||||
// removing POLICY_REJECT should return us to RULE_ALLOW
|
||||
expectSetUidNetworkRules(UID_A, false);
|
||||
expectSetUidMeteredNetworkBlacklist(UID_A, false);
|
||||
expectSetUidForeground(UID_A, false);
|
||||
future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
|
||||
replay();
|
||||
@@ -632,7 +632,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
||||
Future<Void> future;
|
||||
|
||||
// POLICY_REJECT should RULE_REJECT in background
|
||||
expectSetUidNetworkRules(UID_A, true);
|
||||
expectSetUidMeteredNetworkBlacklist(UID_A, true);
|
||||
expectSetUidForeground(UID_A, false);
|
||||
future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
|
||||
replay();
|
||||
@@ -641,7 +641,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
||||
verifyAndReset();
|
||||
|
||||
// uninstall should clear RULE_REJECT
|
||||
expectSetUidNetworkRules(UID_A, false);
|
||||
expectSetUidMeteredNetworkBlacklist(UID_A, false);
|
||||
expectSetUidForeground(UID_A, false);
|
||||
future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
|
||||
replay();
|
||||
@@ -890,9 +890,9 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
|
||||
expectLastCall().atLeastOnce();
|
||||
}
|
||||
|
||||
private void expectSetUidNetworkRules(int uid, boolean rejectOnQuotaInterfaces)
|
||||
private void expectSetUidMeteredNetworkBlacklist(int uid, boolean rejectOnQuotaInterfaces)
|
||||
throws Exception {
|
||||
mNetworkManager.setUidNetworkRules(uid, rejectOnQuotaInterfaces);
|
||||
mNetworkManager.setUidMeteredNetworkBlacklist(uid, rejectOnQuotaInterfaces);
|
||||
expectLastCall().atLeastOnce();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user