From 4bed01d8727b106a1a6bd09a1d82309e1b0df040 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Wed, 7 Sep 2011 18:33:26 -0700 Subject: [PATCH] Fix an issue in how running services are shown. If a process had started services, but another process was using it for more important reasons, it would still be shown as just with running services. Now it will be bundled into the other process that has a dependency on this. This fixes an issue where something like a live wallpaper that say sits forever with a connection to market's licensing service would not show up to the user as using far more memory than it should because it is keeping market running (if market also leaves one of its services running, which it tends to do). Change-Id: I0fd953b7221f7a3b35400007bb9e8437f09d066e --- .../settings/applications/RunningState.java | 96 +++++++++++++++++-- 1 file changed, 89 insertions(+), 7 deletions(-) diff --git a/src/com/android/settings/applications/RunningState.java b/src/com/android/settings/applications/RunningState.java index 552aa56d089..beb96057893 100644 --- a/src/com/android/settings/applications/RunningState.java +++ b/src/com/android/settings/applications/RunningState.java @@ -99,7 +99,20 @@ public class RunningState { // All processes, used for retrieving memory information. final ArrayList mAllProcessItems = new ArrayList(); - + + static class AppProcessInfo { + final ActivityManager.RunningAppProcessInfo info; + boolean hasServices; + boolean hasForegroundServices; + + AppProcessInfo(ActivityManager.RunningAppProcessInfo _info) { + info = _info; + } + } + + // Temporary structure used when updating above information. + final SparseArray mTmpAppProcesses = new SparseArray(); + int mSequence = 0; // ----- following protected by mLock ----- @@ -641,25 +654,97 @@ public class RunningState { mSequence++; boolean changed = false; - + + // Retrieve list of services, filtering out anything that definitely + // won't be shown in the UI. List services = am.getRunningServices(MAX_SERVICES); - final int NS = services != null ? services.size() : 0; + int NS = services != null ? services.size() : 0; for (int i=0; i processes + = am.getRunningAppProcesses(); + final int NP = processes != null ? processes.size() : 0; + mTmpAppProcesses.clear(); + for (int i=0; i 0) { + AppProcessInfo ainfo = mTmpAppProcesses.get(si.pid); + if (ainfo != null) { + ainfo.hasServices = true; + if (si.foreground) { + ainfo.hasForegroundServices = true; + } + } + } + } + + // Update state we are maintaining about process that are running services. + for (int i=0; i 0) { + AppProcessInfo ainfo = mTmpAppProcesses.get(si.pid); + if (ainfo != null && !ainfo.hasForegroundServices) { + // This process does not have any foreground services. + // If its importance is greater than the service importance + // then there is something else more significant that is + // keeping it around that it should possibly be included as + // a part of instead of being shown by itself. + if (ainfo.info.importance + < ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE) { + // Follow process chain to see if there is something + // else that could be shown + boolean skip = false; + ainfo = mTmpAppProcesses.get(ainfo.info.importanceReasonPid); + while (ainfo != null) { + if (ainfo.hasServices || isInterestingProcess(ainfo.info)) { + skip = true; + break; + } + ainfo = mTmpAppProcesses.get(ainfo.info.importanceReasonPid); + } + if (skip) { + continue; + } + } + } + } + HashMap procs = mServiceProcessesByName.get(si.uid); if (procs == null) { procs = new HashMap(); @@ -694,9 +779,6 @@ public class RunningState { // Now update the map of other processes that are running (but // don't have services actively running inside them). - List processes - = am.getRunningAppProcesses(); - final int NP = processes != null ? processes.size() : 0; for (int i=0; i