From 84d3973d854aef6678624aa8773c5b0c12f24419 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Thu, 8 Sep 2016 13:26:55 -0700 Subject: Calls setUidFirewallRules() and enableFirewallChain() asynchronously. The updateRulesForRestrictPowerUL() method is used to set the power-related restrictions for all apps and it ends up by calling NetworkManagerService twice (and each call spawns an iptables process, which takes ~50ms to complete). This method is called on some critical paths, like when the device leaves Doze Light mode. This change makes these calls asynchronously, hence reducing the delay on such critical paths in the O(100ms). Fixes: 31281543 Test: cts-tradefed run commandAndExit cts -m CtsHostsideNetworkTests -t com.android.cts.net.HostsideRestrictBackgroundNetworkTests Change-Id: If720a7112c72a18193ea9614ae187b7ed9c741ec --- .../server/net/NetworkPolicyManagerService.java | 47 ++++++++++++++++++++-- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index ed63613b3829..61b77e776db4 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -90,6 +90,7 @@ import static org.xmlpull.v1.XmlPullParser.START_TAG; import android.Manifest; import android.annotation.IntDef; +import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AppGlobals; import android.app.AppOpsManager; @@ -290,6 +291,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private static final int MSG_UPDATE_INTERFACE_QUOTA = 10; private static final int MSG_REMOVE_INTERFACE_QUOTA = 11; private static final int MSG_RESTRICT_BACKGROUND_BLACKLIST_CHANGED = 12; + private static final int MSG_SET_FIREWALL_RULES = 13; private final Context mContext; private final IActivityManager mActivityManager; @@ -2655,10 +2657,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { uidRules.put(mUidState.keyAt(i), FIREWALL_RULE_ALLOW); } } - setUidFirewallRules(chain, uidRules); + setUidFirewallRulesAsync(chain, uidRules, CHAIN_TOGGLE_ENABLE); + } else { + setUidFirewallRulesAsync(chain, null, CHAIN_TOGGLE_DISABLE); } - - enableFirewallChainUL(chain, enabled); } private boolean isWhitelistedBatterySaverUL(int uid) { @@ -2702,7 +2704,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } - setUidFirewallRules(FIREWALL_CHAIN_STANDBY, uidRules); + setUidFirewallRulesAsync(FIREWALL_CHAIN_STANDBY, uidRules, CHAIN_TOGGLE_NONE); } finally { Trace.traceEnd(Trace.TRACE_TAG_NETWORK); } @@ -3358,6 +3360,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { removeInterfaceQuota((String) msg.obj); return true; } + case MSG_SET_FIREWALL_RULES: { + final int chain = msg.arg1; + final int toggle = msg.arg2; + final SparseIntArray uidRules = (SparseIntArray) msg.obj; + if (uidRules != null) { + setUidFirewallRules(chain, uidRules); + } + if (toggle != CHAIN_TOGGLE_NONE) { + enableFirewallChainUL(chain, toggle == CHAIN_TOGGLE_ENABLE); + } + return true; + } default: { return false; } @@ -3407,6 +3421,31 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } + private static final int CHAIN_TOGGLE_NONE = 0; + private static final int CHAIN_TOGGLE_ENABLE = 1; + private static final int CHAIN_TOGGLE_DISABLE = 2; + @Retention(RetentionPolicy.SOURCE) + @IntDef(flag = false, value = { + CHAIN_TOGGLE_NONE, + CHAIN_TOGGLE_ENABLE, + CHAIN_TOGGLE_DISABLE + }) + public @interface ChainToggleType { + } + + /** + * Calls {@link #setUidFirewallRules(int, SparseIntArray)} and + * {@link #enableFirewallChainUL(int, boolean)} asynchronously. + * + * @param chain firewall chain. + * @param uidRules new UID rules; if {@code null}, only toggles chain state. + * @param toggle whether the chain should be enabled, disabled, or not changed. + */ + private void setUidFirewallRulesAsync(int chain, @Nullable SparseIntArray uidRules, + @ChainToggleType int toggle) { + mHandler.obtainMessage(MSG_SET_FIREWALL_RULES, chain, toggle, uidRules).sendToTarget(); + } + /** * 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 -- cgit v1.2.3-59-g8ed1b