summaryrefslogtreecommitdiffstats
path: root/services/core/java/com/android/server/net
diff options
context:
space:
mode:
authorXiaohui Chen <xiaohuic@google.com>2015-06-17 23:50:23 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-06-17 23:50:28 +0000
commit802ece61399e94bbe98cafaa277c71bee73c03ba (patch)
tree5949aaf315be0c0e89f0cd678b188cc7ee67efc1 /services/core/java/com/android/server/net
parent8b9730f749498491ceb80c86261ee5b8398c7f25 (diff)
parentb41c9f7f39939cee8d226eb5e506c3f0573f44f5 (diff)
downloadframeworks_base-802ece61399e94bbe98cafaa277c71bee73c03ba.zip
frameworks_base-802ece61399e94bbe98cafaa277c71bee73c03ba.tar.gz
frameworks_base-802ece61399e94bbe98cafaa277c71bee73c03ba.tar.bz2
Merge "system_server: add two child chains to firewall" into mnc-dev
Diffstat (limited to 'services/core/java/com/android/server/net')
-rw-r--r--services/core/java/com/android/server/net/LockdownVpnTracker.java9
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java95
2 files changed, 86 insertions, 18 deletions
diff --git a/services/core/java/com/android/server/net/LockdownVpnTracker.java b/services/core/java/com/android/server/net/LockdownVpnTracker.java
index 0f88883..9db6a06 100644
--- a/services/core/java/com/android/server/net/LockdownVpnTracker.java
+++ b/services/core/java/com/android/server/net/LockdownVpnTracker.java
@@ -17,6 +17,7 @@
package com.android.server.net;
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_DEFAULT;
@@ -201,8 +202,8 @@ public class LockdownVpnTracker {
setFirewallEgressSourceRule(addr, true);
}
- mNetService.setFirewallUidRule(ROOT_UID, FIREWALL_RULE_ALLOW);
- mNetService.setFirewallUidRule(Os.getuid(), FIREWALL_RULE_ALLOW);
+ mNetService.setFirewallUidRule(FIREWALL_CHAIN_NONE, ROOT_UID, FIREWALL_RULE_ALLOW);
+ mNetService.setFirewallUidRule(FIREWALL_CHAIN_NONE, Os.getuid(), FIREWALL_RULE_ALLOW);
mErrorCount = 0;
mAcceptedIface = iface;
@@ -291,8 +292,8 @@ public class LockdownVpnTracker {
setFirewallEgressSourceRule(addr, false);
}
- mNetService.setFirewallUidRule(ROOT_UID, FIREWALL_RULE_DEFAULT);
- mNetService.setFirewallUidRule(Os.getuid(), FIREWALL_RULE_DEFAULT);
+ mNetService.setFirewallUidRule(FIREWALL_CHAIN_NONE, ROOT_UID, FIREWALL_RULE_DEFAULT);
+ mNetService.setFirewallUidRule(FIREWALL_CHAIN_NONE,Os.getuid(), FIREWALL_RULE_DEFAULT);
mAcceptedSourceAddr = null;
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index e009455..b0550d6 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -36,8 +36,10 @@ import static android.net.NetworkPolicy.LIMIT_DISABLED;
import static android.net.NetworkPolicy.SNOOZE_NEVER;
import static android.net.NetworkPolicy.WARNING_DISABLED;
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_DEFAULT;
import static android.net.NetworkPolicyManager.POLICY_ALLOW_BACKGROUND_BATTERY_SAVE;
import static android.net.NetworkPolicyManager.POLICY_NONE;
import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
@@ -80,7 +82,6 @@ import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.app.INotificationManager;
-import android.app.IProcessObserver;
import android.app.IUidObserver;
import android.app.Notification;
import android.app.PendingIntent;
@@ -141,7 +142,6 @@ import android.util.Log;
import android.util.NtpTrustedTime;
import android.util.Pair;
import android.util.Slog;
-import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.util.TrustedTime;
@@ -279,6 +279,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
final SparseIntArray mUidPolicy = new SparseIntArray();
/** Currently derived rules for each UID. */
final SparseIntArray mUidRules = new SparseIntArray();
+ final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
/**
* 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);
- final PackageManager pm = mContext.getPackageManager();
-
synchronized (mRulesLock) {
updatePowerSaveWhitelistLocked();
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
// background data use is *not* enabled, since that takes precendence
// 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
// 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},
* {@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
// to have data access. Otherwise, we restrict data access to only
// the top apps.
- mCurForegroundState = (!mRestrictBackground && (mRestrictPower || mDeviceIdleMode))
+ mCurForegroundState = (!mRestrictBackground && mRestrictPower)
? ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
: ActivityManager.PROCESS_STATE_TOP;
+ updateRulesForDeviceIdleLocked();
+
// update rules for all installed applications
final List<UserInfo> users = mUserManager.getUsers();
final List<ApplicationInfo> apps = pm.getInstalledApplications(
@@ -2131,7 +2155,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
// uid in background, and global background disabled
uidRules = RULE_REJECT_METERED;
}
- } else if (mRestrictPower || mDeviceIdleMode) {
+ } else if (mRestrictPower) {
final boolean whitelisted = mPowerSaveWhitelistAppIds.get(appId)
|| mPowerSaveTempWhitelistAppIds.get(appId);
if (!whitelisted && !uidForeground
@@ -2162,7 +2186,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
final boolean oldFirewallReject = (oldRules & RULE_REJECT_ALL) != 0;
final boolean firewallReject = (uidRules & RULE_REJECT_ALL) != 0;
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
@@ -2314,14 +2343,34 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
}
/**
+ * Set uid rules on a particular firewall chain. This is going to synchronize the rules given
+ * here to netd. It will clean up dead rules and make sure the target chain only contains rules
+ * specified here.
+ */
+ private void setUidFirewallRules(int chain, SparseIntArray uidRules) {
+ try {
+ int size = uidRules.size();
+ 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) {
+ 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.
- * @param uid
- * @param rejectOnAll
*/
- private void setUidFirewallRules(int uid, boolean rejectOnAll) {
+ private void setUidFirewallRule(int chain, int uid, boolean rejectOnAll) {
try {
- mNetworkManager.setFirewallUidRule(uid,
- rejectOnAll ? FIREWALL_RULE_DENY : FIREWALL_RULE_DEFAULT);
+ 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) {
@@ -2329,6 +2378,24 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub
}
}
+ /**
+ * 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) {
try {
return mNetworkStats.getNetworkTotalBytes(template, start, end);