diff options
author | Dianne Hackborn <hackbod@google.com> | 2011-09-07 18:33:26 -0700 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2011-09-07 18:47:36 -0700 |
commit | 4bed01d8727b106a1a6bd09a1d82309e1b0df040 (patch) | |
tree | 7a1005816c146be60775339e975b55c09cea8859 | |
parent | 9b9db3f966c86befa424b497266cb3493ac24977 (diff) | |
download | packages_apps_Settings-4bed01d8727b106a1a6bd09a1d82309e1b0df040.zip packages_apps_Settings-4bed01d8727b106a1a6bd09a1d82309e1b0df040.tar.gz packages_apps_Settings-4bed01d8727b106a1a6bd09a1d82309e1b0df040.tar.bz2 |
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
-rw-r--r-- | src/com/android/settings/applications/RunningState.java | 96 |
1 files changed, 89 insertions, 7 deletions
diff --git a/src/com/android/settings/applications/RunningState.java b/src/com/android/settings/applications/RunningState.java index 552aa56..beb9605 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<ProcessItem> mAllProcessItems = new ArrayList<ProcessItem>(); - + + 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<AppProcessInfo> mTmpAppProcesses = new SparseArray<AppProcessInfo>(); + 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<ActivityManager.RunningServiceInfo> 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<NS; i++) { ActivityManager.RunningServiceInfo si = services.get(i); // We are not interested in services that have not been started // and don't have a known client, because // there is nothing the user can do about them. if (!si.started && si.clientLabel == 0) { + services.remove(i); + i--; + NS--; continue; } // We likewise don't care about services running in a // persistent process like the system or phone. if ((si.flags&ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS) != 0) { + services.remove(i); + i--; + NS--; continue; } - + } + + // Retrieve list of running processes, organizing them into a sparse + // array for easy retrieval. + List<ActivityManager.RunningAppProcessInfo> processes + = am.getRunningAppProcesses(); + final int NP = processes != null ? processes.size() : 0; + mTmpAppProcesses.clear(); + for (int i=0; i<NP; i++) { + ActivityManager.RunningAppProcessInfo pi = processes.get(i); + mTmpAppProcesses.put(pi.pid, new AppProcessInfo(pi)); + } + + // Initial iteration through running services to collect per-process + // info about them. + for (int i=0; i<NS; i++) { + ActivityManager.RunningServiceInfo si = services.get(i); + if (si.restarting == 0 && si.pid > 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<NS; i++) { + ActivityManager.RunningServiceInfo si = services.get(i); + + // If this service's process is in use at a higher importance + // due to another process bound to one of its services, then we + // won't put it in the top-level list of services. Instead we + // want it to be included in the set of processes that the other + // process needs. + if (si.restarting == 0 && si.pid > 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<String, ProcessItem> procs = mServiceProcessesByName.get(si.uid); if (procs == null) { procs = new HashMap<String, ProcessItem>(); @@ -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<ActivityManager.RunningAppProcessInfo> processes - = am.getRunningAppProcesses(); - final int NP = processes != null ? processes.size() : 0; for (int i=0; i<NP; i++) { ActivityManager.RunningAppProcessInfo pi = processes.get(i); ProcessItem proc = mServiceProcessesByPid.get(pi.pid); |