summaryrefslogtreecommitdiff
path: root/services/java/com/android/server/am
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2013-10-31 16:32:44 -0700
committerDianne Hackborn <hackbod@google.com>2013-10-31 16:32:44 -0700
commitdb92608de9b4acccee1e3232264c9830ad300c4f (patch)
tree92e4ef0147cf4181c7c50560ac1cad3aeb3da08d /services/java/com/android/server/am
parent714ba34556572d36b1f9f8d9b860c4da24da6361 (diff)
downloadbase-db92608de9b4acccee1e3232264c9830ad300c4f.tar.gz
Fix issue #11168649: LRU logic for Chrome renderers seems...
...not to work on KitKat (was: Janky exit animation) Reworking the LRU list (splitting it into an activity vs. empty section) accidentally broken the old behavior of "client activity" processes being prioritized with activity processes. In fact, we were no longer marking "client activity" processes at all. In this change, we rework how we manage "client activity" processes by putting them on the main activity LRU section. This is generally simple -- ActiveServices now keeps track of whether a process is a "client activity" process based on its bindings, and updateLruProcess treats these as regular activity processes. However, we don't want to allow processes doing this to spam our LRU list so that we lose everything else, so there is some additional complexity in managing that list where we spread client activity processes across is so that the intermingle with other activity processes. The rest of the change is fairly simple -- the old client activity process management is gone, but that doesn't matter because it wasn't actually running any more. There is a new argument to updateLruProcess to indicate a client process it comes from (since we now need to update this based on bindings) which is just used to limit how high in the LRU list we can move things. The ProcessRecord.hasActivities field is simply removied, because ProcessRecord.activities.size() > 0 means the same thing, and that is actually what all of the key mechanisms are using at this point. Finally, note there is some commented out code of a new way to manage the LRU movement. This isn't in use, but something I would like to move to in the next release so it is staying there for now for further development. Change-Id: Id8a21b4e32bb5aa9c8e7d443de4b658487cfbe18
Diffstat (limited to 'services/java/com/android/server/am')
-rw-r--r--services/java/com/android/server/am/ActiveServices.java55
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java230
-rw-r--r--services/java/com/android/server/am/ActivityStack.java8
-rw-r--r--services/java/com/android/server/am/ActivityStackSupervisor.java3
-rw-r--r--services/java/com/android/server/am/BroadcastQueue.java3
-rw-r--r--services/java/com/android/server/am/ProcessRecord.java6
6 files changed, 224 insertions, 81 deletions
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java
index a64940ca2420..6186b9e7ca35 100644
--- a/services/java/com/android/server/am/ActiveServices.java
+++ b/services/java/com/android/server/am/ActiveServices.java
@@ -564,7 +564,7 @@ public final class ActiveServices {
if (r.isForeground) {
r.isForeground = false;
if (r.app != null) {
- mAm.updateLruProcessLocked(r.app, false, false);
+ mAm.updateLruProcessLocked(r.app, false, null);
updateServiceForegroundLocked(r.app, true);
}
}
@@ -597,6 +597,42 @@ public final class ActiveServices {
}
}
+ private boolean updateServiceClientActivitiesLocked(ProcessRecord proc,
+ ConnectionRecord modCr) {
+ if (modCr != null && modCr.binding.client != null) {
+ if (modCr.binding.client.activities.size() <= 0) {
+ // This connection is from a client without activities, so adding
+ // and removing is not interesting.
+ return false;
+ }
+ }
+
+ boolean anyClientActivities = false;
+ for (int i=proc.services.size()-1; i>=0 && !anyClientActivities; i--) {
+ ServiceRecord sr = proc.services.valueAt(i);
+ for (int conni=sr.connections.size()-1; conni>=0 && !anyClientActivities; conni--) {
+ ArrayList<ConnectionRecord> clist = sr.connections.valueAt(conni);
+ for (int cri=clist.size()-1; cri>=0; cri--) {
+ ConnectionRecord cr = clist.get(cri);
+ if (cr.binding.client == null || cr.binding.client == proc) {
+ // Binding to ourself is not interesting.
+ continue;
+ }
+ if (cr.binding.client.activities.size() > 0) {
+ anyClientActivities = true;
+ break;
+ }
+ }
+ }
+ }
+ if (anyClientActivities != proc.hasClientActivities) {
+ proc.hasClientActivities = anyClientActivities;
+ mAm.updateLruProcessLocked(proc, anyClientActivities, null);
+ return true;
+ }
+ return false;
+ }
+
int bindServiceLocked(IApplicationThread caller, IBinder token,
Intent service, String resolvedType,
IServiceConnection connection, int flags, int userId) {
@@ -698,6 +734,9 @@ public final class ActiveServices {
if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
b.client.hasAboveClient = true;
}
+ if (s.app != null) {
+ updateServiceClientActivitiesLocked(s.app, c);
+ }
clist = mServiceConnections.get(binder);
if (clist == null) {
clist = new ArrayList<ConnectionRecord>();
@@ -714,6 +753,7 @@ public final class ActiveServices {
if (s.app != null) {
// This could have made the service more important.
+ mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities, b.client);
mAm.updateOomAdjLocked(s.app);
}
@@ -1316,7 +1356,8 @@ public final class ActiveServices {
app.services.add(r);
bumpServiceExecutingLocked(r, execInFg, "create");
- mAm.updateLruProcessLocked(app, true, false);
+ mAm.updateLruProcessLocked(app, false, null);
+ mAm.updateOomAdjLocked();
boolean created = false;
try {
@@ -1601,6 +1642,9 @@ public final class ActiveServices {
if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
b.client.updateHasAboveClientLocked();
}
+ if (s.app != null) {
+ updateServiceClientActivitiesLocked(s.app, c);
+ }
}
clist = mServiceConnections.get(binder);
if (clist != null) {
@@ -1621,6 +1665,13 @@ public final class ActiveServices {
&& b.intent.hasBound) {
try {
bumpServiceExecutingLocked(s, false, "unbind");
+ if (b.client != s.app && (c.flags&Context.BIND_WAIVE_PRIORITY) == 0
+ && s.app.setProcState <= ActivityManager.PROCESS_STATE_RECEIVER) {
+ // If this service's process is not already in the cached list,
+ // then update it in the LRU list here because this may be causing
+ // it to go down there and we want it to start out near the top.
+ mAm.updateLruProcessLocked(s.app, false, null);
+ }
mAm.updateOomAdjLocked(s.app);
b.intent.hasBound = false;
// Assume the client doesn't want to know about a rebind;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 7cef0a4845b2..844f46403401 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -33,7 +33,6 @@ import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.ProcessStats;
-import com.android.internal.app.ResolverActivity;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.ProcessCpuTracker;
@@ -217,6 +216,7 @@ public final class ActivityManagerService extends ActivityManagerNative
static final boolean DEBUG_IMMERSIVE = localLOGV || false;
static final boolean DEBUG_MU = localLOGV || false;
static final boolean DEBUG_OOM_ADJ = localLOGV || false;
+ static final boolean DEBUG_LRU = localLOGV || false;
static final boolean DEBUG_PAUSE = localLOGV || false;
static final boolean DEBUG_POWER = localLOGV || false;
static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
@@ -1739,7 +1739,8 @@ public final class ActivityManagerService extends ActivityManagerNative
synchronized (mSelf.mPidsSelfLocked) {
mSelf.mPidsSelfLocked.put(app.pid, app);
}
- mSelf.updateLruProcessLocked(app, true, false);
+ mSelf.updateLruProcessLocked(app, false, null);
+ mSelf.updateOomAdjLocked();
}
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
@@ -2265,7 +2266,7 @@ public final class ActivityManagerService extends ActivityManagerNative
int lrui = mLruProcesses.lastIndexOf(app);
if (lrui < 0) {
- Log.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
+ Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
+ what + " " + obj + " from " + srcApp);
return index;
}
@@ -2285,6 +2286,8 @@ public final class ActivityManagerService extends ActivityManagerNative
if (index > 0) {
index--;
}
+ if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
+ + " in LRU list: " + app);
mLruProcesses.add(index, app);
return index;
}
@@ -2302,8 +2305,9 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- final void updateLruProcessLocked(ProcessRecord app, boolean oomAdj, boolean activityChange) {
- final boolean hasActivity = app.activities.size() > 0;
+ final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
+ ProcessRecord client) {
+ final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
final boolean hasService = false; // not impl yet. app.services.size() > 0;
if (!activityChange && hasActivity) {
// The process has activties, so we are only going to allow activity-based
@@ -2317,8 +2321,65 @@ public final class ActivityManagerService extends ActivityManagerNative
final long now = SystemClock.uptimeMillis();
app.lastActivityTime = now;
+ // First a quick reject: if the app is already at the position we will
+ // put it, then there is nothing to do.
+ if (hasActivity) {
+ final int N = mLruProcesses.size();
+ if (N > 0 && mLruProcesses.get(N-1) == app) {
+ if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
+ return;
+ }
+ } else {
+ if (mLruProcessServiceStart > 0
+ && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
+ if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
+ return;
+ }
+ }
+
int lrui = mLruProcesses.lastIndexOf(app);
+ if (app.persistent && lrui >= 0) {
+ // We don't care about the position of persistent processes, as long as
+ // they are in the list.
+ if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
+ return;
+ }
+
+ /* In progress: compute new position first, so we can avoid doing work
+ if the process is not actually going to move. Not yet working.
+ int addIndex;
+ int nextIndex;
+ boolean inActivity = false, inService = false;
+ if (hasActivity) {
+ // Process has activities, put it at the very tipsy-top.
+ addIndex = mLruProcesses.size();
+ nextIndex = mLruProcessServiceStart;
+ inActivity = true;
+ } else if (hasService) {
+ // Process has services, put it at the top of the service list.
+ addIndex = mLruProcessActivityStart;
+ nextIndex = mLruProcessServiceStart;
+ inActivity = true;
+ inService = true;
+ } else {
+ // Process not otherwise of interest, it goes to the top of the non-service area.
+ addIndex = mLruProcessServiceStart;
+ if (client != null) {
+ int clientIndex = mLruProcesses.lastIndexOf(client);
+ if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
+ + app);
+ if (clientIndex >= 0 && addIndex > clientIndex) {
+ addIndex = clientIndex;
+ }
+ }
+ nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
+ }
+
+ Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
+ + mLruProcessActivityStart + "): " + app);
+ */
+
if (lrui >= 0) {
if (lrui < mLruProcessActivityStart) {
mLruProcessActivityStart--;
@@ -2326,23 +2387,91 @@ public final class ActivityManagerService extends ActivityManagerNative
if (lrui < mLruProcessServiceStart) {
mLruProcessServiceStart--;
}
+ /*
+ if (addIndex > lrui) {
+ addIndex--;
+ }
+ if (nextIndex > lrui) {
+ nextIndex--;
+ }
+ */
mLruProcesses.remove(lrui);
}
+ /*
+ mLruProcesses.add(addIndex, app);
+ if (inActivity) {
+ mLruProcessActivityStart++;
+ }
+ if (inService) {
+ mLruProcessActivityStart++;
+ }
+ */
+
int nextIndex;
if (hasActivity) {
- // Process has activities, put it at the very tipsy-top.
- mLruProcesses.add(app);
- nextIndex = mLruProcessActivityStart;
+ final int N = mLruProcesses.size();
+ if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
+ // Process doesn't have activities, but has clients with
+ // activities... move it up, but one below the top (the top
+ // should always have a real activity).
+ if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
+ mLruProcesses.add(N-1, app);
+ // To keep it from spamming the LRU list (by making a bunch of clients),
+ // we will push down any other entries owned by the app.
+ final int uid = app.info.uid;
+ for (int i=N-2; i>mLruProcessActivityStart; i--) {
+ ProcessRecord subProc = mLruProcesses.get(i);
+ if (subProc.info.uid == uid) {
+ // We want to push this one down the list. If the process after
+ // it is for the same uid, however, don't do so, because we don't
+ // want them internally to be re-ordered.
+ if (mLruProcesses.get(i-1).info.uid != uid) {
+ if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
+ + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
+ ProcessRecord tmp = mLruProcesses.get(i);
+ mLruProcesses.set(i, mLruProcesses.get(i-1));
+ mLruProcesses.set(i-1, tmp);
+ i--;
+ }
+ } else {
+ // A gap, we can stop here.
+ break;
+ }
+ }
+ } else {
+ // Process has activities, put it at the very tipsy-top.
+ if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
+ mLruProcesses.add(app);
+ }
+ nextIndex = mLruProcessServiceStart;
} else if (hasService) {
// Process has services, put it at the top of the service list.
+ if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
mLruProcesses.add(mLruProcessActivityStart, app);
nextIndex = mLruProcessServiceStart;
mLruProcessActivityStart++;
} else {
// Process not otherwise of interest, it goes to the top of the non-service area.
- mLruProcesses.add(mLruProcessServiceStart, app);
- nextIndex = mLruProcessServiceStart-1;
+ int index = mLruProcessServiceStart;
+ if (client != null) {
+ // If there is a client, don't allow the process to be moved up higher
+ // in the list than that client.
+ int clientIndex = mLruProcesses.lastIndexOf(client);
+ if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
+ + " when updating " + app);
+ if (clientIndex <= lrui) {
+ // Don't allow the client index restriction to push it down farther in the
+ // list than it already is.
+ clientIndex = lrui;
+ }
+ if (clientIndex >= 0 && index > clientIndex) {
+ index = clientIndex;
+ }
+ }
+ if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
+ mLruProcesses.add(index, app);
+ nextIndex = index-1;
mLruProcessActivityStart++;
mLruProcessServiceStart++;
}
@@ -2353,23 +2482,19 @@ public final class ActivityManagerService extends ActivityManagerNative
ConnectionRecord cr = app.connections.valueAt(j);
if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
&& cr.binding.service.app != null
- && cr.binding.service.app.lruSeq != mLruSeq) {
+ && cr.binding.service.app.lruSeq != mLruSeq
+ && !cr.binding.service.app.persistent) {
nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
"service connection", cr, app);
}
}
for (int j=app.conProviders.size()-1; j>=0; j--) {
ContentProviderRecord cpr = app.conProviders.get(j).provider;
- if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
+ if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
"provider reference", cpr, app);
}
}
-
- //Slog.i(TAG, "Putting proc to front: " + app.processName);
- if (oomAdj) {
- updateOomAdjLocked();
- }
}
final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
@@ -4826,7 +4951,7 @@ public final class ActivityManagerService extends ActivityManagerNative
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
mCoreSettingsObserver.getCoreSettingsLocked());
- updateLruProcessLocked(app, false, false);
+ updateLruProcessLocked(app, false, null);
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
} catch (Exception e) {
// todo: Yikes! What should we do? For now we will try to
@@ -7414,7 +7539,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// make sure to count it as being accessed and thus
// back up on the LRU list. This is good because
// content providers are often expensive to start.
- updateLruProcessLocked(cpr.proc, false, false);
+ updateLruProcessLocked(cpr.proc, false, null);
}
}
@@ -8023,7 +8148,8 @@ public final class ActivityManagerService extends ActivityManagerNative
if (isolated) {
mIsolatedProcesses.put(app.uid, app);
}
- updateLruProcessLocked(app, true, false);
+ updateLruProcessLocked(app, false, null);
+ updateOomAdjLocked();
}
// This package really, really can not be stopped.
@@ -10095,7 +10221,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (app.persistent) {
outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
}
- if (app.hasActivities) {
+ if (app.activities.size() > 0) {
outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
}
outInfo.lastTrimLevel = app.trimMemoryLevel;
@@ -11851,7 +11977,7 @@ public final class ActivityManagerService extends ActivityManagerNative
thread = r.thread;
pid = r.pid;
oomAdj = r.getSetAdjWithServices();
- hasActivities = r.hasActivities;
+ hasActivities = r.activities.size() > 0;
}
if (thread != null) {
if (!isCheckinRequest && dumpDetails) {
@@ -14073,7 +14199,6 @@ public final class ActivityManagerService extends ActivityManagerNative
app.adjTarget = null;
app.empty = false;
app.cached = false;
- app.hasClientActivities = false;
final int activitiesSize = app.activities.size();
@@ -14083,7 +14208,6 @@ public final class ActivityManagerService extends ActivityManagerNative
app.adjType = "fixed";
app.adjSeq = mAdjSeq;
app.curRawAdj = app.maxAdj;
- app.hasActivities = false;
app.foregroundActivities = false;
app.keeping = true;
app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
@@ -14095,16 +14219,12 @@ public final class ActivityManagerService extends ActivityManagerNative
app.systemNoUi = true;
if (app == TOP_APP) {
app.systemNoUi = false;
- app.hasActivities = true;
} else if (activitiesSize > 0) {
for (int j = 0; j < activitiesSize; j++) {
final ActivityRecord r = app.activities.get(j);
if (r.visible) {
app.systemNoUi = false;
}
- if (r.app == app) {
- app.hasActivities = true;
- }
}
}
if (!app.systemNoUi) {
@@ -14115,7 +14235,6 @@ public final class ActivityManagerService extends ActivityManagerNative
app.keeping = false;
app.systemNoUi = false;
- app.hasActivities = false;
// Determine the importance of the process, starting with most
// important to least, and assign an appropriate OOM adjustment.
@@ -14132,7 +14251,6 @@ public final class ActivityManagerService extends ActivityManagerNative
app.adjType = "top-activity";
foregroundActivities = true;
interesting = true;
- app.hasActivities = true;
procState = ActivityManager.PROCESS_STATE_TOP;
} else if (app.instrumentationClass != null) {
// Don't want to kill running instrumentation.
@@ -14181,7 +14299,6 @@ public final class ActivityManagerService extends ActivityManagerNative
+ app + "?!?");
continue;
}
- app.hasActivities = true;
if (r.visible) {
// App has a visible activity; only upgrade adjustment.
if (adj > ProcessList.VISIBLE_APP_ADJ) {
@@ -14430,27 +14547,6 @@ public final class ActivityManagerService extends ActivityManagerNative
clientAdj = adj;
}
}
- } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
- if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
- // If this connection is keeping the service
- // created, then we want to try to better follow
- // its memory management semantics for activities.
- // That is, if it is sitting in the background
- // LRU list as a cached process (with activities),
- // we don't want the service it is connected to
- // to go into the empty LRU and quickly get killed,
- // because all we'll do is just end up restarting
- // the service.
- if (client.hasActivities) {
- if (procState >
- ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT) {
- procState =
- ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
- app.adjType = "cch-client-act";
- }
- app.hasClientActivities = true;
- }
- }
}
if (adj > clientAdj) {
// If this process has recently shown UI, and
@@ -14668,6 +14764,12 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
+ if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
+ // This is a cached process, but with client activities. Mark it so.
+ procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
+ app.adjType = "cch-client-act";
+ }
+
if (adj == ProcessList.SERVICE_ADJ) {
if (doingAll) {
app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
@@ -15296,7 +15398,6 @@ public final class ActivityManagerService extends ActivityManagerNative
// application processes based on their current state.
int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
int nextCachedAdj = curCachedAdj+1;
- int curClientCachedAdj = curCachedAdj+1;
int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
int nextEmptyAdj = curEmptyAdj+2;
for (int i=N-1; i>=0; i--) {
@@ -15311,11 +15412,15 @@ public final class ActivityManagerService extends ActivityManagerNative
if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
switch (app.curProcState) {
case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
+ case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
// This process is a cached process holding activities...
// assign it the next cached value for that type, and then
// step that cached level.
app.curRawAdj = curCachedAdj;
app.curAdj = app.modifyRawOomAdj(curCachedAdj);
+ if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
+ + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
+ + ")");
if (curCachedAdj != nextCachedAdj) {
stepCached++;
if (stepCached >= cachedFactor) {
@@ -15325,25 +15430,9 @@ public final class ActivityManagerService extends ActivityManagerNative
if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
}
- if (curClientCachedAdj <= curCachedAdj) {
- curClientCachedAdj = curCachedAdj + 1;
- if (curClientCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
- curClientCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
- }
- }
}
}
break;
- case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
- // Special case for cached client processes... just step
- // down from after regular cached processes.
- app.curRawAdj = curClientCachedAdj;
- app.curAdj = app.modifyRawOomAdj(curClientCachedAdj);
- curClientCachedAdj++;
- if (curClientCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
- curClientCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
- }
- break;
default:
// For everything else, assign next empty cached process
// level and bump that up. Note that this means that
@@ -15352,6 +15441,9 @@ public final class ActivityManagerService extends ActivityManagerNative
// state is still as a service), which is what we want.
app.curRawAdj = curEmptyAdj;
app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
+ if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
+ + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
+ + ")");
if (curEmptyAdj != nextEmptyAdj) {
stepEmpty++;
if (stepEmpty >= emptyFactor) {
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 2e5dedfb15d8..ed047242fb14 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -61,7 +61,6 @@ import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -1398,7 +1397,7 @@ final class ActivityStack {
if (next.app != null && next.app.thread != null) {
// No reason to do full oom adj update here; we'll let that
// happen whenever it needs to later.
- mService.updateLruProcessLocked(next.app, false, true);
+ mService.updateLruProcessLocked(next.app, true, null);
}
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
@@ -1526,8 +1525,9 @@ final class ActivityStack {
mResumedActivity = next;
next.task.touchActiveTime();
mService.addRecentTaskLocked(next.task);
- mService.updateLruProcessLocked(next.app, true, true);
+ mService.updateLruProcessLocked(next.app, true, null);
updateLRUListLocked(next);
+ mService.updateOomAdjLocked();
// Have the window manager re-evaluate the orientation of
// the screen based on the new activity order.
@@ -2781,7 +2781,7 @@ final class ActivityStack {
}
if (r.app.activities.isEmpty()) {
// No longer have activities, so update LRU list and oom adj.
- mService.updateLruProcessLocked(r.app, false, false);
+ mService.updateLruProcessLocked(r.app, false, null);
mService.updateOomAdjLocked();
}
}
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index 7650a65324b7..82513643ff0f 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -905,7 +905,8 @@ public final class ActivityStackSupervisor {
if (idx < 0) {
app.activities.add(r);
}
- mService.updateLruProcessLocked(app, true, true);
+ mService.updateLruProcessLocked(app, true, null);
+ mService.updateOomAdjLocked();
final ActivityStack stack = r.task.stack;
try {
diff --git a/services/java/com/android/server/am/BroadcastQueue.java b/services/java/com/android/server/am/BroadcastQueue.java
index 5e80135ec8e2..dd3d8aa5eca2 100644
--- a/services/java/com/android/server/am/BroadcastQueue.java
+++ b/services/java/com/android/server/am/BroadcastQueue.java
@@ -220,7 +220,8 @@ public final class BroadcastQueue {
r.curApp = app;
app.curReceiver = r;
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER);
- mService.updateLruProcessLocked(app, true, false);
+ mService.updateLruProcessLocked(app, false, null);
+ mService.updateOomAdjLocked();
// Tell the application to launch this receiver.
r.intent.setComponent(r.curComponent);
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index 486e9163b4fc..187cd441d8ca 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -86,7 +86,6 @@ final class ProcessRecord {
boolean keeping; // Actively running code so don't kill due to that?
boolean setIsForeground; // Running foreground UI when last set?
boolean notCachedSinceIdle; // Has this process not been in a cached state since last idle?
- boolean hasActivities; // Are there any activities running in this process?
boolean hasClientActivities; // Are there any client services with activities?
boolean hasStartedServices; // Are there any started services running in this process?
boolean foregroundServices; // Running any services that are foreground?
@@ -265,9 +264,8 @@ final class ProcessRecord {
pw.print(prefix); pw.print("persistent="); pw.print(persistent);
pw.print(" removed="); pw.println(removed);
}
- if (hasActivities || hasClientActivities || foregroundActivities) {
- pw.print(prefix); pw.print("hasActivities="); pw.print(hasActivities);
- pw.print(" hasClientActivities="); pw.print(hasClientActivities);
+ if (hasClientActivities || foregroundActivities) {
+ pw.print(prefix); pw.print("hasClientActivities="); pw.print(hasClientActivities);
pw.print(" foregroundActivities="); pw.println(foregroundActivities);
}
if (hasStartedServices) {