Merge "system_server: add two child chains to firewall" into mnc-dev
This commit is contained in:
@@ -61,6 +61,17 @@ public class NetworkPolicyManager {
|
|||||||
public static final int FIREWALL_RULE_ALLOW = 1;
|
public static final int FIREWALL_RULE_ALLOW = 1;
|
||||||
public static final int FIREWALL_RULE_DENY = 2;
|
public static final int FIREWALL_RULE_DENY = 2;
|
||||||
|
|
||||||
|
public static final int FIREWALL_TYPE_WHITELIST = 0;
|
||||||
|
public static final int FIREWALL_TYPE_BLACKLIST = 1;
|
||||||
|
|
||||||
|
public static final int FIREWALL_CHAIN_NONE = 0;
|
||||||
|
public static final int FIREWALL_CHAIN_DOZABLE = 1;
|
||||||
|
public static final int FIREWALL_CHAIN_STANDBY = 2;
|
||||||
|
|
||||||
|
public static final String FIREWALL_CHAIN_NAME_NONE = "none";
|
||||||
|
public static final String FIREWALL_CHAIN_NAME_DOZABLE = "dozable";
|
||||||
|
public static final String FIREWALL_CHAIN_NAME_STANDBY = "standby";
|
||||||
|
|
||||||
private static final boolean ALLOW_PLATFORM_APP_POLICY = true;
|
private static final boolean ALLOW_PLATFORM_APP_POLICY = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -342,7 +342,9 @@ interface INetworkManagementService
|
|||||||
void setFirewallInterfaceRule(String iface, boolean allow);
|
void setFirewallInterfaceRule(String iface, boolean allow);
|
||||||
void setFirewallEgressSourceRule(String addr, boolean allow);
|
void setFirewallEgressSourceRule(String addr, boolean allow);
|
||||||
void setFirewallEgressDestRule(String addr, int port, boolean allow);
|
void setFirewallEgressDestRule(String addr, int port, boolean allow);
|
||||||
void setFirewallUidRule(int uid, int rule);
|
void setFirewallUidRule(int chain, int uid, int rule);
|
||||||
|
void setFirewallUidRules(int chain, in int[] uids, in int[] rules);
|
||||||
|
void setFirewallChainEnabled(int chain, boolean enable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set all packets from users in ranges to go through VPN specified by netId.
|
* Set all packets from users in ranges to go through VPN specified by netId.
|
||||||
|
|||||||
@@ -19,6 +19,15 @@ package com.android.server;
|
|||||||
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
|
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
|
||||||
import static android.Manifest.permission.DUMP;
|
import static android.Manifest.permission.DUMP;
|
||||||
import static android.Manifest.permission.SHUTDOWN;
|
import static android.Manifest.permission.SHUTDOWN;
|
||||||
|
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE;
|
||||||
|
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE;
|
||||||
|
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_NONE;
|
||||||
|
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY;
|
||||||
|
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NONE;
|
||||||
|
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY;
|
||||||
|
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
|
||||||
|
import static android.net.NetworkPolicyManager.FIREWALL_TYPE_BLACKLIST;
|
||||||
|
import static android.net.NetworkPolicyManager.FIREWALL_TYPE_WHITELIST;
|
||||||
import static android.net.NetworkStats.SET_DEFAULT;
|
import static android.net.NetworkStats.SET_DEFAULT;
|
||||||
import static android.net.NetworkStats.TAG_ALL;
|
import static android.net.NetworkStats.TAG_ALL;
|
||||||
import static android.net.NetworkStats.TAG_NONE;
|
import static android.net.NetworkStats.TAG_NONE;
|
||||||
@@ -35,6 +44,7 @@ import static com.android.server.NetworkManagementService.NetdResponseCode.Tethe
|
|||||||
import static com.android.server.NetworkManagementService.NetdResponseCode.TtyListResult;
|
import static com.android.server.NetworkManagementService.NetdResponseCode.TtyListResult;
|
||||||
import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
|
import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
import android.app.ActivityManagerNative;
|
import android.app.ActivityManagerNative;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
@@ -192,6 +202,21 @@ public class NetworkManagementService extends INetworkManagementService.Stub
|
|||||||
/** Set of UIDs that are to be blocked/allowed by firewall controller. */
|
/** Set of UIDs that are to be blocked/allowed by firewall controller. */
|
||||||
@GuardedBy("mQuotaLock")
|
@GuardedBy("mQuotaLock")
|
||||||
private SparseIntArray mUidFirewallRules = new SparseIntArray();
|
private SparseIntArray mUidFirewallRules = new SparseIntArray();
|
||||||
|
/**
|
||||||
|
* Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches
|
||||||
|
* to application idles.
|
||||||
|
*/
|
||||||
|
@GuardedBy("mQuotaLock")
|
||||||
|
private SparseIntArray mUidFirewallStandbyRules = new SparseIntArray();
|
||||||
|
/**
|
||||||
|
* Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches
|
||||||
|
* to device idles.
|
||||||
|
*/
|
||||||
|
@GuardedBy("mQuotaLock")
|
||||||
|
private SparseIntArray mUidFirewallDozableRules = new SparseIntArray();
|
||||||
|
|
||||||
|
private boolean mStandbyChainEnabled = false;
|
||||||
|
private boolean mDozableChainEnabled = false;
|
||||||
|
|
||||||
private Object mIdleTimerLock = new Object();
|
private Object mIdleTimerLock = new Object();
|
||||||
/** Set of interfaces with active idle timers. */
|
/** Set of interfaces with active idle timers. */
|
||||||
@@ -282,6 +307,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void systemReady() {
|
public void systemReady() {
|
||||||
|
// init firewall states
|
||||||
|
mDozableChainEnabled = false;
|
||||||
|
mStandbyChainEnabled = true;
|
||||||
prepareNativeDaemon();
|
prepareNativeDaemon();
|
||||||
if (DBG) Slog.d(TAG, "Prepared");
|
if (DBG) Slog.d(TAG, "Prepared");
|
||||||
}
|
}
|
||||||
@@ -568,9 +596,38 @@ public class NetworkManagementService extends INetworkManagementService.Stub
|
|||||||
final SparseIntArray uidFirewallRules = mUidFirewallRules;
|
final SparseIntArray uidFirewallRules = mUidFirewallRules;
|
||||||
mUidFirewallRules = new SparseIntArray();
|
mUidFirewallRules = new SparseIntArray();
|
||||||
for (int i = 0; i < uidFirewallRules.size(); i++) {
|
for (int i = 0; i < uidFirewallRules.size(); i++) {
|
||||||
setFirewallUidRule(uidFirewallRules.keyAt(i), uidFirewallRules.valueAt(i));
|
setFirewallUidRuleInternal(FIREWALL_CHAIN_NONE, uidFirewallRules.keyAt(i),
|
||||||
|
uidFirewallRules.valueAt(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size = mUidFirewallStandbyRules.size();
|
||||||
|
if (size > 0) {
|
||||||
|
Slog.d(TAG, "Pushing " + size + " active firewall standby UID rules");
|
||||||
|
final SparseIntArray uidFirewallRules = mUidFirewallStandbyRules;
|
||||||
|
mUidFirewallStandbyRules = new SparseIntArray();
|
||||||
|
for (int i = 0; i < uidFirewallRules.size(); i++) {
|
||||||
|
setFirewallUidRuleInternal(FIREWALL_CHAIN_STANDBY, uidFirewallRules.keyAt(i),
|
||||||
|
uidFirewallRules.valueAt(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mStandbyChainEnabled) {
|
||||||
|
setFirewallChainEnabled(FIREWALL_CHAIN_STANDBY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
size = mUidFirewallDozableRules.size();
|
||||||
|
if (size > 0) {
|
||||||
|
Slog.d(TAG, "Pushing " + size + " active firewall dozable UID rules");
|
||||||
|
final SparseIntArray uidFirewallRules = mUidFirewallDozableRules;
|
||||||
|
mUidFirewallDozableRules = new SparseIntArray();
|
||||||
|
for (int i = 0; i < uidFirewallRules.size(); i++) {
|
||||||
|
setFirewallUidRuleInternal(FIREWALL_CHAIN_DOZABLE, uidFirewallRules.keyAt(i),
|
||||||
|
uidFirewallRules.valueAt(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mDozableChainEnabled) {
|
||||||
|
setFirewallChainEnabled(FIREWALL_CHAIN_DOZABLE, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1954,13 +2011,78 @@ public class NetworkManagementService extends INetworkManagementService.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setFirewallUidRule(int uid, int rule) {
|
public void setFirewallChainEnabled(int chain, boolean enable) {
|
||||||
enforceSystemUid();
|
enforceSystemUid();
|
||||||
if (rule == NetworkPolicyManager.FIREWALL_RULE_ALLOW) {
|
final String operation = enable ? "enable_chain" : "disable_chain";
|
||||||
Preconditions.checkState(mFirewallEnabled);
|
try {
|
||||||
|
String chainName;
|
||||||
|
switch(chain) {
|
||||||
|
case FIREWALL_CHAIN_STANDBY:
|
||||||
|
chainName = FIREWALL_CHAIN_NAME_STANDBY;
|
||||||
|
mStandbyChainEnabled = enable;
|
||||||
|
break;
|
||||||
|
case FIREWALL_CHAIN_DOZABLE:
|
||||||
|
chainName = FIREWALL_CHAIN_NAME_DOZABLE;
|
||||||
|
mDozableChainEnabled = enable;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Bad child chain: " + chain);
|
||||||
|
}
|
||||||
|
mConnector.execute("firewall", operation, chainName);
|
||||||
|
} catch (NativeDaemonConnectorException e) {
|
||||||
|
throw e.rethrowAsParcelableException();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getFirewallType(int chain) {
|
||||||
|
switch (chain) {
|
||||||
|
case FIREWALL_CHAIN_STANDBY:
|
||||||
|
return FIREWALL_TYPE_BLACKLIST;
|
||||||
|
case FIREWALL_CHAIN_DOZABLE:
|
||||||
|
return FIREWALL_TYPE_WHITELIST;
|
||||||
|
default:
|
||||||
|
return isFirewallEnabled() ? FIREWALL_TYPE_WHITELIST : FIREWALL_TYPE_BLACKLIST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFirewallUidRules(int chain, int[] uids, int[] rules) {
|
||||||
|
enforceSystemUid();
|
||||||
|
SparseIntArray uidFirewallRules = getUidFirewallRules(chain);
|
||||||
|
SparseIntArray newRules = new SparseIntArray();
|
||||||
|
// apply new set of rules
|
||||||
|
for (int index = uids.length - 1; index >= 0; --index) {
|
||||||
|
int uid = uids[index];
|
||||||
|
int rule = rules[index];
|
||||||
|
setFirewallUidRule(chain, uid, rule);
|
||||||
|
newRules.put(uid, rule);
|
||||||
|
}
|
||||||
|
// collect the rules to remove.
|
||||||
|
SparseIntArray rulesToRemove = new SparseIntArray();
|
||||||
|
for (int index = uidFirewallRules.size() - 1; index >= 0; --index) {
|
||||||
|
int uid = uidFirewallRules.keyAt(index);
|
||||||
|
if (newRules.indexOfKey(uid) < 0) {
|
||||||
|
rulesToRemove.put(uid, FIREWALL_RULE_DEFAULT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// remove dead rules
|
||||||
|
for (int index = rulesToRemove.size() - 1; index >= 0; --index) {
|
||||||
|
int uid = rulesToRemove.keyAt(index);
|
||||||
|
setFirewallUidRuleInternal(chain, uid, FIREWALL_RULE_DEFAULT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFirewallUidRule(int chain, int uid, int rule) {
|
||||||
|
enforceSystemUid();
|
||||||
|
setFirewallUidRuleInternal(chain, uid, rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setFirewallUidRuleInternal(int chain, int uid, int rule) {
|
||||||
synchronized (mQuotaLock) {
|
synchronized (mQuotaLock) {
|
||||||
final int oldUidFirewallRule = mUidFirewallRules.get(uid);
|
SparseIntArray uidFirewallRules = getUidFirewallRules(chain);
|
||||||
|
|
||||||
|
final int oldUidFirewallRule = uidFirewallRules.get(uid, FIREWALL_RULE_DEFAULT);
|
||||||
if (DBG) {
|
if (DBG) {
|
||||||
Slog.d(TAG, "oldRule = " + oldUidFirewallRule
|
Slog.d(TAG, "oldRule = " + oldUidFirewallRule
|
||||||
+ ", newRule=" + rule + " for uid=" + uid);
|
+ ", newRule=" + rule + " for uid=" + uid);
|
||||||
@@ -1973,7 +2095,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
String ruleName;
|
String ruleName;
|
||||||
if (isFirewallEnabled()) { // Whitelist mode
|
if (getFirewallType(chain) == FIREWALL_TYPE_WHITELIST) {
|
||||||
if (rule == NetworkPolicyManager.FIREWALL_RULE_ALLOW) {
|
if (rule == NetworkPolicyManager.FIREWALL_RULE_ALLOW) {
|
||||||
ruleName = "allow";
|
ruleName = "allow";
|
||||||
} else {
|
} else {
|
||||||
@@ -1988,17 +2110,44 @@ public class NetworkManagementService extends INetworkManagementService.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) {
|
if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) {
|
||||||
mUidFirewallRules.delete(uid);
|
uidFirewallRules.delete(uid);
|
||||||
} else {
|
} else {
|
||||||
mUidFirewallRules.put(uid, rule);
|
uidFirewallRules.put(uid, rule);
|
||||||
}
|
}
|
||||||
mConnector.execute("firewall", "set_uid_rule", uid, ruleName);
|
mConnector.execute("firewall", "set_uid_rule", getFirewallChainName(chain), uid,
|
||||||
|
ruleName);
|
||||||
} catch (NativeDaemonConnectorException e) {
|
} catch (NativeDaemonConnectorException e) {
|
||||||
throw e.rethrowAsParcelableException();
|
throw e.rethrowAsParcelableException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private @NonNull SparseIntArray getUidFirewallRules(int chain) {
|
||||||
|
switch (chain) {
|
||||||
|
case FIREWALL_CHAIN_STANDBY:
|
||||||
|
return mUidFirewallStandbyRules;
|
||||||
|
case FIREWALL_CHAIN_DOZABLE:
|
||||||
|
return mUidFirewallDozableRules;
|
||||||
|
case FIREWALL_CHAIN_NONE:
|
||||||
|
return mUidFirewallRules;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unknown chain:" + chain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NonNull String getFirewallChainName(int chain) {
|
||||||
|
switch (chain) {
|
||||||
|
case FIREWALL_CHAIN_STANDBY:
|
||||||
|
return FIREWALL_CHAIN_NAME_STANDBY;
|
||||||
|
case FIREWALL_CHAIN_DOZABLE:
|
||||||
|
return FIREWALL_CHAIN_NAME_DOZABLE;
|
||||||
|
case FIREWALL_CHAIN_NONE:
|
||||||
|
return FIREWALL_CHAIN_NAME_NONE;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unknown chain:" + chain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void enforceSystemUid() {
|
private static void enforceSystemUid() {
|
||||||
final int uid = Binder.getCallingUid();
|
final int uid = Binder.getCallingUid();
|
||||||
if (uid != Process.SYSTEM_UID) {
|
if (uid != Process.SYSTEM_UID) {
|
||||||
@@ -2123,6 +2272,32 @@ public class NetworkManagementService extends INetworkManagementService.Stub
|
|||||||
pw.println("]");
|
pw.println("]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pw.println("UID firewall standby chain enabled: " + mStandbyChainEnabled);
|
||||||
|
synchronized (mUidFirewallStandbyRules) {
|
||||||
|
pw.print("UID firewall standby rule: [");
|
||||||
|
final int size = mUidFirewallStandbyRules.size();
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
pw.print(mUidFirewallStandbyRules.keyAt(i));
|
||||||
|
pw.print(":");
|
||||||
|
pw.print(mUidFirewallStandbyRules.valueAt(i));
|
||||||
|
if (i < size - 1) pw.print(",");
|
||||||
|
}
|
||||||
|
pw.println("]");
|
||||||
|
}
|
||||||
|
|
||||||
|
pw.println("UID firewall dozable chain enabled: " + mDozableChainEnabled);
|
||||||
|
synchronized (mUidFirewallDozableRules) {
|
||||||
|
pw.print("UID firewall dozable rule: [");
|
||||||
|
final int size = mUidFirewallDozableRules.size();
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
pw.print(mUidFirewallDozableRules.keyAt(i));
|
||||||
|
pw.print(":");
|
||||||
|
pw.print(mUidFirewallDozableRules.valueAt(i));
|
||||||
|
if (i < size - 1) pw.print(",");
|
||||||
|
}
|
||||||
|
pw.println("]");
|
||||||
|
}
|
||||||
|
|
||||||
synchronized (mIdleTimerLock) {
|
synchronized (mIdleTimerLock) {
|
||||||
pw.println("Idle timers:");
|
pw.println("Idle timers:");
|
||||||
for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) {
|
for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.android.server.net;
|
package com.android.server.net;
|
||||||
|
|
||||||
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
|
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
|
||||||
|
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NONE;
|
||||||
import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW;
|
import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW;
|
||||||
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
|
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
|
||||||
|
|
||||||
@@ -201,8 +202,8 @@ public class LockdownVpnTracker {
|
|||||||
setFirewallEgressSourceRule(addr, true);
|
setFirewallEgressSourceRule(addr, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
mNetService.setFirewallUidRule(ROOT_UID, FIREWALL_RULE_ALLOW);
|
mNetService.setFirewallUidRule(FIREWALL_CHAIN_NONE, ROOT_UID, FIREWALL_RULE_ALLOW);
|
||||||
mNetService.setFirewallUidRule(Os.getuid(), FIREWALL_RULE_ALLOW);
|
mNetService.setFirewallUidRule(FIREWALL_CHAIN_NONE, Os.getuid(), FIREWALL_RULE_ALLOW);
|
||||||
|
|
||||||
mErrorCount = 0;
|
mErrorCount = 0;
|
||||||
mAcceptedIface = iface;
|
mAcceptedIface = iface;
|
||||||
@@ -291,8 +292,8 @@ public class LockdownVpnTracker {
|
|||||||
setFirewallEgressSourceRule(addr, false);
|
setFirewallEgressSourceRule(addr, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
mNetService.setFirewallUidRule(ROOT_UID, FIREWALL_RULE_DEFAULT);
|
mNetService.setFirewallUidRule(FIREWALL_CHAIN_NONE, ROOT_UID, FIREWALL_RULE_DEFAULT);
|
||||||
mNetService.setFirewallUidRule(Os.getuid(), FIREWALL_RULE_DEFAULT);
|
mNetService.setFirewallUidRule(FIREWALL_CHAIN_NONE,Os.getuid(), FIREWALL_RULE_DEFAULT);
|
||||||
|
|
||||||
mAcceptedSourceAddr = null;
|
mAcceptedSourceAddr = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,8 +36,10 @@ import static android.net.NetworkPolicy.LIMIT_DISABLED;
|
|||||||
import static android.net.NetworkPolicy.SNOOZE_NEVER;
|
import static android.net.NetworkPolicy.SNOOZE_NEVER;
|
||||||
import static android.net.NetworkPolicy.WARNING_DISABLED;
|
import static android.net.NetworkPolicy.WARNING_DISABLED;
|
||||||
import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
|
import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
|
||||||
|
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE;
|
||||||
|
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY;
|
||||||
|
import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW;
|
||||||
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY;
|
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY;
|
||||||
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
|
|
||||||
import static android.net.NetworkPolicyManager.POLICY_ALLOW_BACKGROUND_BATTERY_SAVE;
|
import static android.net.NetworkPolicyManager.POLICY_ALLOW_BACKGROUND_BATTERY_SAVE;
|
||||||
import static android.net.NetworkPolicyManager.POLICY_NONE;
|
import static android.net.NetworkPolicyManager.POLICY_NONE;
|
||||||
import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
|
import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
|
||||||
@@ -80,7 +82,6 @@ import android.app.AppGlobals;
|
|||||||
import android.app.AppOpsManager;
|
import android.app.AppOpsManager;
|
||||||
import android.app.IActivityManager;
|
import android.app.IActivityManager;
|
||||||
import android.app.INotificationManager;
|
import android.app.INotificationManager;
|
||||||
import android.app.IProcessObserver;
|
|
||||||
import android.app.IUidObserver;
|
import android.app.IUidObserver;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
@@ -141,7 +142,6 @@ import android.util.Log;
|
|||||||
import android.util.NtpTrustedTime;
|
import android.util.NtpTrustedTime;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseArray;
|
|
||||||
import android.util.SparseBooleanArray;
|
import android.util.SparseBooleanArray;
|
||||||
import android.util.SparseIntArray;
|
import android.util.SparseIntArray;
|
||||||
import android.util.TrustedTime;
|
import android.util.TrustedTime;
|
||||||
@@ -279,6 +279,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
|
|||||||
final SparseIntArray mUidPolicy = new SparseIntArray();
|
final SparseIntArray mUidPolicy = new SparseIntArray();
|
||||||
/** Currently derived rules for each UID. */
|
/** Currently derived rules for each UID. */
|
||||||
final SparseIntArray mUidRules = new SparseIntArray();
|
final SparseIntArray mUidRules = new SparseIntArray();
|
||||||
|
final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UIDs that have been white-listed to always be able to have network access
|
* UIDs that have been white-listed to always be able to have network access
|
||||||
@@ -412,8 +413,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
|
|||||||
|
|
||||||
mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
|
mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
|
||||||
|
|
||||||
final PackageManager pm = mContext.getPackageManager();
|
|
||||||
|
|
||||||
synchronized (mRulesLock) {
|
synchronized (mRulesLock) {
|
||||||
updatePowerSaveWhitelistLocked();
|
updatePowerSaveWhitelistLocked();
|
||||||
mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
|
mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
|
||||||
@@ -1103,7 +1102,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
|
|||||||
// will not have a bandwidth limit. Also only do this if restrict
|
// will not have a bandwidth limit. Also only do this if restrict
|
||||||
// background data use is *not* enabled, since that takes precendence
|
// background data use is *not* enabled, since that takes precendence
|
||||||
// use over those networks can have a cost associated with it).
|
// use over those networks can have a cost associated with it).
|
||||||
final boolean powerSave = (mRestrictPower || mDeviceIdleMode) && !mRestrictBackground;
|
final boolean powerSave = mRestrictPower && !mRestrictBackground;
|
||||||
|
|
||||||
// First, generate identities of all connected networks so we can
|
// First, generate identities of all connected networks so we can
|
||||||
// quickly compare them against all defined policies below.
|
// quickly compare them against all defined policies below.
|
||||||
@@ -2024,6 +2023,29 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateRulesForDeviceIdleLocked() {
|
||||||
|
if (mDeviceIdleMode) {
|
||||||
|
// sync the whitelists before enable dozable chain. We don't care about the rules if
|
||||||
|
// we are disabling the chain.
|
||||||
|
SparseIntArray uidRules = new SparseIntArray();
|
||||||
|
final List<UserInfo> users = mUserManager.getUsers();
|
||||||
|
for (UserInfo user : users) {
|
||||||
|
for (int i = mPowerSaveTempWhitelistAppIds.size() - 1; i >= 0; i--) {
|
||||||
|
int appId = mPowerSaveTempWhitelistAppIds.keyAt(i);
|
||||||
|
int uid = UserHandle.getUid(user.id, appId);
|
||||||
|
uidRules.put(uid, FIREWALL_RULE_ALLOW);
|
||||||
|
}
|
||||||
|
for (int i = mPowerSaveWhitelistAppIds.size() - 1; i >= 0; i--) {
|
||||||
|
int appId = mPowerSaveWhitelistAppIds.keyAt(i);
|
||||||
|
int uid = UserHandle.getUid(user.id, appId);
|
||||||
|
uidRules.put(uid, FIREWALL_RULE_ALLOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setUidFirewallRules(FIREWALL_CHAIN_DOZABLE, uidRules);
|
||||||
|
}
|
||||||
|
enableFirewallChain(FIREWALL_CHAIN_DOZABLE, mDeviceIdleMode);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update rules that might be changed by {@link #mRestrictBackground},
|
* Update rules that might be changed by {@link #mRestrictBackground},
|
||||||
* {@link #mRestrictPower}, or {@link #mDeviceIdleMode} value.
|
* {@link #mRestrictPower}, or {@link #mDeviceIdleMode} value.
|
||||||
@@ -2034,10 +2056,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
|
|||||||
// If we are in restrict power mode, we allow all important apps
|
// If we are in restrict power mode, we allow all important apps
|
||||||
// to have data access. Otherwise, we restrict data access to only
|
// to have data access. Otherwise, we restrict data access to only
|
||||||
// the top apps.
|
// the top apps.
|
||||||
mCurForegroundState = (!mRestrictBackground && (mRestrictPower || mDeviceIdleMode))
|
mCurForegroundState = (!mRestrictBackground && mRestrictPower)
|
||||||
? ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
|
? ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
|
||||||
: ActivityManager.PROCESS_STATE_TOP;
|
: ActivityManager.PROCESS_STATE_TOP;
|
||||||
|
|
||||||
|
updateRulesForDeviceIdleLocked();
|
||||||
|
|
||||||
// update rules for all installed applications
|
// update rules for all installed applications
|
||||||
final List<UserInfo> users = mUserManager.getUsers();
|
final List<UserInfo> users = mUserManager.getUsers();
|
||||||
final List<ApplicationInfo> apps = pm.getInstalledApplications(
|
final List<ApplicationInfo> apps = pm.getInstalledApplications(
|
||||||
@@ -2131,7 +2155,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
|
|||||||
// uid in background, and global background disabled
|
// uid in background, and global background disabled
|
||||||
uidRules = RULE_REJECT_METERED;
|
uidRules = RULE_REJECT_METERED;
|
||||||
}
|
}
|
||||||
} else if (mRestrictPower || mDeviceIdleMode) {
|
} else if (mRestrictPower) {
|
||||||
final boolean whitelisted = mPowerSaveWhitelistAppIds.get(appId)
|
final boolean whitelisted = mPowerSaveWhitelistAppIds.get(appId)
|
||||||
|| mPowerSaveTempWhitelistAppIds.get(appId);
|
|| mPowerSaveTempWhitelistAppIds.get(appId);
|
||||||
if (!whitelisted && !uidForeground
|
if (!whitelisted && !uidForeground
|
||||||
@@ -2162,7 +2186,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
|
|||||||
final boolean oldFirewallReject = (oldRules & RULE_REJECT_ALL) != 0;
|
final boolean oldFirewallReject = (oldRules & RULE_REJECT_ALL) != 0;
|
||||||
final boolean firewallReject = (uidRules & RULE_REJECT_ALL) != 0;
|
final boolean firewallReject = (uidRules & RULE_REJECT_ALL) != 0;
|
||||||
if (oldFirewallReject != firewallReject) {
|
if (oldFirewallReject != firewallReject) {
|
||||||
setUidFirewallRules(uid, firewallReject);
|
setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, firewallReject);
|
||||||
|
if (mDeviceIdleMode && !firewallReject) {
|
||||||
|
// if we are in device idle mode, and we decide to allow this uid. we need to punch
|
||||||
|
// a hole in the device idle chain.
|
||||||
|
setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, uid, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// dispatch changed rule to existing listeners
|
// dispatch changed rule to existing listeners
|
||||||
@@ -2314,14 +2343,20 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add or remove a uid to the firewall blacklist for all network ifaces.
|
* Set uid rules on a particular firewall chain. This is going to synchronize the rules given
|
||||||
* @param uid
|
* here to netd. It will clean up dead rules and make sure the target chain only contains rules
|
||||||
* @param rejectOnAll
|
* specified here.
|
||||||
*/
|
*/
|
||||||
private void setUidFirewallRules(int uid, boolean rejectOnAll) {
|
private void setUidFirewallRules(int chain, SparseIntArray uidRules) {
|
||||||
try {
|
try {
|
||||||
mNetworkManager.setFirewallUidRule(uid,
|
int size = uidRules.size();
|
||||||
rejectOnAll ? FIREWALL_RULE_DENY : FIREWALL_RULE_DEFAULT);
|
int[] uids = new int[size];
|
||||||
|
int[] rules = new int[size];
|
||||||
|
for(int index = size - 1; index >= 0; --index) {
|
||||||
|
uids[index] = uidRules.keyAt(index);
|
||||||
|
rules[index] = uidRules.valueAt(index);
|
||||||
|
}
|
||||||
|
mNetworkManager.setFirewallUidRules(chain, uids, rules);
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
Log.wtf(TAG, "problem setting firewall uid rules", e);
|
Log.wtf(TAG, "problem setting firewall uid rules", e);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -2329,6 +2364,38 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add or remove a uid to the firewall blacklist for all network ifaces.
|
||||||
|
*/
|
||||||
|
private void setUidFirewallRule(int chain, int uid, boolean rejectOnAll) {
|
||||||
|
try {
|
||||||
|
mNetworkManager.setFirewallUidRule(chain, uid,
|
||||||
|
rejectOnAll ? FIREWALL_RULE_DENY : FIREWALL_RULE_ALLOW);
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
Log.wtf(TAG, "problem setting firewall uid rules", e);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
// ignored; service lives in system_server
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add or remove a uid to the firewall blacklist for all network ifaces.
|
||||||
|
*/
|
||||||
|
private void enableFirewallChain(int chain, boolean enable) {
|
||||||
|
if (mFirewallChainStates.indexOfKey(chain) >= 0 &&
|
||||||
|
mFirewallChainStates.get(chain) == enable) {
|
||||||
|
// All is the same, nothing to do.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
mNetworkManager.setFirewallChainEnabled(chain, enable);
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
Log.wtf(TAG, "problem enable firewall chain", e);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
// ignored; service lives in system_server
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private long getTotalBytes(NetworkTemplate template, long start, long end) {
|
private long getTotalBytes(NetworkTemplate template, long start, long end) {
|
||||||
try {
|
try {
|
||||||
return mNetworkStats.getNetworkTotalBytes(template, start, end);
|
return mNetworkStats.getNetworkTotalBytes(template, start, end);
|
||||||
|
|||||||
Reference in New Issue
Block a user