From 6f7af03cf13f76f48e63937e13e4a1c508d100d6 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Tue, 1 Nov 2011 18:25:15 -0700 Subject: [PATCH] Process AMS events in NetworkPolicy handler. When a process changes foreground status or dies, NetworkPolicy updates its internal state with a lock held. In cases where there is contention, this can block the AMS handler and prevent other events, such as broadcasts, from being dispatched. This change moves the incoming AMS events to an existing internal NetworkPolicy handler thread, where they can execute without blocking AMS. Bug: 5497544 Change-Id: Ie0c620a620fd9f0f4eb02af510bd819efa4deb6a --- .../net/NetworkPolicyManagerService.java | 70 +++++++++++-------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java index e6107826aa8c9..bdad82a6d8fa9 100644 --- a/services/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java @@ -186,8 +186,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS; - private static final int MSG_RULES_CHANGED = 0x1; - private static final int MSG_METERED_IFACES_CHANGED = 0x2; + private static final int MSG_RULES_CHANGED = 1; + private static final int MSG_METERED_IFACES_CHANGED = 2; + private static final int MSG_FOREGROUND_ACTIVITIES_CHANGED = 3; + private static final int MSG_PROCESS_DIED = 4; private final Context mContext; private final IActivityManager mActivityManager; @@ -335,37 +337,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private IProcessObserver mProcessObserver = new IProcessObserver.Stub() { @Override public void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) { - // only someone like AMS should only be calling us - mContext.enforceCallingOrSelfPermission(MANAGE_APP_TOKENS, TAG); - - synchronized (mRulesLock) { - // because a uid can have multiple pids running inside, we need to - // remember all pid states and summarize foreground at uid level. - - // record foreground for this specific pid - SparseBooleanArray pidForeground = mUidPidForeground.get(uid); - if (pidForeground == null) { - pidForeground = new SparseBooleanArray(2); - mUidPidForeground.put(uid, pidForeground); - } - pidForeground.put(pid, foregroundActivities); - computeUidForegroundLocked(uid); - } + mHandler.obtainMessage(MSG_FOREGROUND_ACTIVITIES_CHANGED, + pid, uid, foregroundActivities).sendToTarget(); } @Override public void onProcessDied(int pid, int uid) { - // only someone like AMS should only be calling us - mContext.enforceCallingOrSelfPermission(MANAGE_APP_TOKENS, TAG); - - synchronized (mRulesLock) { - // clear records and recompute, when they exist - final SparseBooleanArray pidForeground = mUidPidForeground.get(uid); - if (pidForeground != null) { - pidForeground.delete(pid); - computeUidForegroundLocked(uid); - } - } + mHandler.obtainMessage(MSG_PROCESS_DIED, pid, uid).sendToTarget(); } }; @@ -1469,6 +1447,40 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { mListeners.finishBroadcast(); return true; } + case MSG_FOREGROUND_ACTIVITIES_CHANGED: { + final int pid = msg.arg1; + final int uid = msg.arg2; + final boolean foregroundActivities = (Boolean) msg.obj; + + synchronized (mRulesLock) { + // because a uid can have multiple pids running inside, we need to + // remember all pid states and summarize foreground at uid level. + + // record foreground for this specific pid + SparseBooleanArray pidForeground = mUidPidForeground.get(uid); + if (pidForeground == null) { + pidForeground = new SparseBooleanArray(2); + mUidPidForeground.put(uid, pidForeground); + } + pidForeground.put(pid, foregroundActivities); + computeUidForegroundLocked(uid); + } + return true; + } + case MSG_PROCESS_DIED: { + final int pid = msg.arg1; + final int uid = msg.arg2; + + synchronized (mRulesLock) { + // clear records and recompute, when they exist + final SparseBooleanArray pidForeground = mUidPidForeground.get(uid); + if (pidForeground != null) { + pidForeground.delete(pid); + computeUidForegroundLocked(uid); + } + } + return true; + } default: { return false; }