summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmds/am/src/com/android/commands/am/Am.java5
-rw-r--r--core/java/android/app/ActivityManagerNative.java2
-rw-r--r--core/java/android/app/ActivityThread.java7
-rw-r--r--core/java/android/content/Context.java15
-rw-r--r--services/java/com/android/server/am/ActiveServices.java16
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java240
-rw-r--r--services/java/com/android/server/am/ActivityRecord.java6
-rwxr-xr-xservices/java/com/android/server/am/ActivityStack.java26
-rw-r--r--services/java/com/android/server/am/BroadcastFilter.java2
-rw-r--r--services/java/com/android/server/am/BroadcastQueue.java14
-rw-r--r--services/java/com/android/server/am/BroadcastRecord.java2
-rw-r--r--services/java/com/android/server/am/ConnectionRecord.java9
-rw-r--r--services/java/com/android/server/am/ContentProviderRecord.java3
-rw-r--r--services/java/com/android/server/am/EventLogTags.logtags66
-rw-r--r--services/java/com/android/server/am/ProcessList.java19
-rw-r--r--services/java/com/android/server/am/ProcessRecord.java44
-rw-r--r--services/java/com/android/server/am/ServiceRecord.java1
17 files changed, 313 insertions, 164 deletions
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index bc9e74e..396b32f 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -804,8 +804,9 @@ public class Am {
ParcelFileDescriptor fd = null;
try {
- fd = ParcelFileDescriptor.open(
- new File(heapFile),
+ File file = new File(heapFile);
+ file.delete();
+ fd = ParcelFileDescriptor.open(file,
ParcelFileDescriptor.MODE_CREATE |
ParcelFileDescriptor.MODE_TRUNCATE |
ParcelFileDescriptor.MODE_READ_WRITE);
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 9b08493..9874b0b 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1509,9 +1509,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
case DUMP_HEAP_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
String process = data.readString();
+ int userId = data.readInt();
boolean managed = data.readInt() != 0;
String path = data.readString();
- int userId = data.readInt();
ParcelFileDescriptor fd = data.readInt() != 0
? data.readFileDescriptor() : null;
boolean res = dumpHeap(process, userId, managed, path, fd);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index d4b204f..6638433 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2711,7 +2711,7 @@ public final class ActivityThread {
r.activity.performResume();
EventLog.writeEvent(LOG_ON_RESUME_CALLED,
- r.activity.getComponentName().getClassName());
+ UserHandle.myUserId(), r.activity.getComponentName().getClassName());
r.paused = false;
r.stopped = false;
@@ -2979,7 +2979,8 @@ public final class ActivityThread {
// Now we are idle.
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
- EventLog.writeEvent(LOG_ON_PAUSE_CALLED, r.activity.getComponentName().getClassName());
+ EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
+ r.activity.getComponentName().getClassName());
if (!r.activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
@@ -3364,7 +3365,7 @@ public final class ActivityThread {
try {
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
- EventLog.writeEvent(LOG_ON_PAUSE_CALLED,
+ EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
r.activity.getComponentName().getClassName());
if (!r.activity.mCalled) {
throw new SuperNotCalledException(
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index ac36cf7..201b43f 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -178,7 +178,7 @@ public abstract class Context {
* Flag for {@link #bindService}: indicates that the client application
* binding to this service considers the service to be more important than
* the app itself. When set, the platform will try to have the out of
- * memory kill the app before it kills the service it is bound to, though
+ * memory killer kill the app before it kills the service it is bound to, though
* this is not guaranteed to be the case.
*/
public static final int BIND_ABOVE_CLIENT = 0x0008;
@@ -219,6 +219,19 @@ public abstract class Context {
public static final int BIND_ADJUST_WITH_ACTIVITY = 0x0080;
/**
+ * @hide An idea that is not yet implemented.
+ * Flag for {@link #bindService}: If binding from an activity, consider
+ * this service to be visible like the binding activity is. That is,
+ * it will be treated as something more important to keep around than
+ * invisible background activities. This will impact the number of
+ * recent activities the user can switch between without having them
+ * restart. There is no guarantee this will be respected, as the system
+ * tries to balance such requests from one app vs. the importantance of
+ * keeping other apps around.
+ */
+ public static final int BIND_VISIBLE = 0x0100;
+
+ /**
* Flag for {@link #bindService}: Don't consider the bound service to be
* visible, even if the caller is visible.
* @hide
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java
index 0c0f00c..1269433 100644
--- a/services/java/com/android/server/am/ActiveServices.java
+++ b/services/java/com/android/server/am/ActiveServices.java
@@ -44,7 +44,6 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
-import android.content.pm.UserInfo;
import android.os.Binder;
import android.os.IBinder;
import android.os.Message;
@@ -391,7 +390,7 @@ public class ActiveServices {
if (r.isForeground) {
r.isForeground = false;
if (r.app != null) {
- mAm.updateLruProcessLocked(r.app, false, true);
+ mAm.updateLruProcessLocked(r.app, false);
updateServiceForegroundLocked(r.app, true);
}
}
@@ -760,7 +759,8 @@ public class ActiveServices {
int N = mPendingServices.size();
for (int i=0; i<N; i++) {
ServiceRecord pr = mPendingServices.get(i);
- if (pr.name.equals(name)) {
+ if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
+ && pr.name.equals(name)) {
mPendingServices.remove(i);
i--;
N--;
@@ -942,7 +942,7 @@ public class ActiveServices {
Slog.w(TAG, "Scheduling restart of crashed service "
+ r.shortName + " in " + r.restartDelay + "ms");
EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
- r.shortName, r.restartDelay);
+ r.userId, r.shortName, r.restartDelay);
return canceled;
}
@@ -1083,14 +1083,14 @@ public class ActiveServices {
app.services.add(r);
bumpServiceExecutingLocked(r, "create");
- mAm.updateLruProcessLocked(app, true, true);
+ mAm.updateLruProcessLocked(app, true);
boolean created = false;
try {
mAm.mStringBuilder.setLength(0);
r.intent.getIntent().toShortString(mAm.mStringBuilder, true, false, true, false);
EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
- System.identityHashCode(r), r.shortName,
+ r.userId, System.identityHashCode(r), r.shortName,
mAm.mStringBuilder.toString(), r.app.pid);
synchronized (r.stats.getBatteryStats()) {
r.stats.startLaunchedLocked();
@@ -1240,7 +1240,7 @@ public class ActiveServices {
if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
- System.identityHashCode(r), r.shortName,
+ r.userId, System.identityHashCode(r), r.shortName,
(r.app != null) ? r.app.pid : -1);
mServiceMap.removeServiceByName(r.name, r.userId);
@@ -1664,7 +1664,7 @@ public class ActiveServices {
Slog.w(TAG, "Service crashed " + sr.crashCount
+ " times, stopping: " + sr);
EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
- sr.crashCount, sr.shortName, app.pid);
+ sr.userId, sr.crashCount, sr.shortName, app.pid);
bringDownServiceLocked(sr, true);
} else if (!allowRestart) {
bringDownServiceLocked(sr, true);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index b266bd4..370d427 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1369,7 +1369,7 @@ public final class ActivityManagerService extends ActivityManagerNative
synchronized (mSelf.mPidsSelfLocked) {
mSelf.mPidsSelfLocked.put(app.pid, app);
}
- mSelf.updateLruProcessLocked(app, true, true);
+ mSelf.updateLruProcessLocked(app, true);
}
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
@@ -1805,8 +1805,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- private final void updateLruProcessInternalLocked(ProcessRecord app,
- boolean updateActivityTime, int bestPos) {
+ private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) {
// put it on the LRU to keep track of when it should be exited.
int lrui = mLruProcesses.indexOf(app);
if (lrui >= 0) mLruProcesses.remove(lrui);
@@ -1817,9 +1816,7 @@ public final class ActivityManagerService extends ActivityManagerNative
app.lruSeq = mLruSeq;
// compute the new weight for this process.
- if (updateActivityTime) {
- app.lastActivityTime = SystemClock.uptimeMillis();
- }
+ app.lastActivityTime = SystemClock.uptimeMillis();
if (app.activities.size() > 0) {
// If this process has activities, we more strongly want to keep
// it around.
@@ -1863,24 +1860,22 @@ public final class ActivityManagerService extends ActivityManagerNative
if (cr.binding != null && cr.binding.service != null
&& cr.binding.service.app != null
&& cr.binding.service.app.lruSeq != mLruSeq) {
- updateLruProcessInternalLocked(cr.binding.service.app,
- updateActivityTime, i+1);
+ updateLruProcessInternalLocked(cr.binding.service.app, i+1);
}
}
}
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) {
- updateLruProcessInternalLocked(cpr.proc,
- updateActivityTime, i+1);
+ updateLruProcessInternalLocked(cpr.proc, i+1);
}
}
}
final void updateLruProcessLocked(ProcessRecord app,
- boolean oomAdj, boolean updateActivityTime) {
+ boolean oomAdj) {
mLruSeq++;
- updateLruProcessInternalLocked(app, updateActivityTime, 0);
+ updateLruProcessInternalLocked(app, 0);
//Slog.i(TAG, "Putting proc to front: " + app.processName);
if (oomAdj) {
@@ -1981,7 +1976,8 @@ public final class ActivityManagerService extends ActivityManagerNative
+ "/" + info.processName);
mProcessCrashTimes.remove(info.processName, info.uid);
if (mBadProcesses.get(info.processName, info.uid) != null) {
- EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
+ EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
+ UserHandle.getUserId(info.uid), info.uid,
info.processName);
mBadProcesses.remove(info.processName, info.uid);
if (app != null) {
@@ -2129,7 +2125,8 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
+ EventLog.writeEvent(EventLogTags.AM_PROC_START,
+ UserHandle.getUserId(uid), startResult.pid, uid,
app.processName, hostingType,
hostingNameStr != null ? hostingNameStr : "");
@@ -2946,7 +2943,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (!r.finishing) {
Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
- System.identityHashCode(r),
+ r.userId, System.identityHashCode(r),
r.task.taskId, r.shortComponentName,
"proc died without state saved");
}
@@ -3037,7 +3034,7 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.i(TAG, "Process " + app.processName + " (pid " + pid
+ ") has died.");
}
- EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
+ EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
if (localLOGV) Slog.v(
TAG, "Dying app: " + app + ", pid: " + pid
+ ", thread: " + thread.asBinder());
@@ -3086,7 +3083,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// A new process has already been started.
Slog.i(TAG, "Process " + app.processName + " (pid " + pid
+ ") has died and restarted (pid " + app.pid + ").");
- EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
+ EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
} else if (DEBUG_PROCESSES) {
Slog.d(TAG, "Received spurious death notification for thread "
+ thread.asBinder());
@@ -3321,8 +3318,8 @@ public final class ActivityManagerService extends ActivityManagerNative
app.notResponding = true;
// Log the ANR to the event log.
- EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
- annotation);
+ EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
+ app.processName, app.info.flags, annotation);
// Dump thread traces as quickly as we can, starting with "interesting" processes.
firstPids.add(app.pid);
@@ -3408,7 +3405,7 @@ public final class ActivityManagerService extends ActivityManagerNative
synchronized (this) {
if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Slog.w(TAG, "Killing " + app + ": background ANR");
- EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
app.processName, app.setAdj, "background ANR");
Process.killProcessQuiet(app.pid);
return;
@@ -4077,8 +4074,8 @@ public final class ActivityManagerService extends ActivityManagerNative
if (gone) {
Slog.w(TAG, "Process " + app + " failed to attach");
- EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
- app.processName);
+ EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
+ pid, app.uid, app.processName);
mProcessNames.remove(app.processName, app.uid);
mIsolatedProcesses.remove(app.uid);
if (mHeavyWeightProcess == app) {
@@ -4090,7 +4087,7 @@ public final class ActivityManagerService extends ActivityManagerNative
checkAppInLaunchingProvidersLocked(app, true);
// Take care of any services that are waiting for the process.
mServices.processStartTimedOutLocked(app);
- EventLog.writeEvent(EventLogTags.AM_KILL, pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid,
app.processName, app.setAdj, "start timeout");
Process.killProcessQuiet(pid);
if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
@@ -4166,7 +4163,7 @@ public final class ActivityManagerService extends ActivityManagerNative
return false;
}
- EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
+ EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
app.thread = thread;
app.curAdj = app.setAdj = -100;
@@ -4244,7 +4241,7 @@ public final class ActivityManagerService extends ActivityManagerNative
enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
mCoreSettingsObserver.getCoreSettingsLocked());
- updateLruProcessLocked(app, false, true);
+ updateLruProcessLocked(app, false);
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
} catch (Exception e) {
// todo: Yikes! What should we do? For now we will try to
@@ -5914,7 +5911,7 @@ public final class ActivityManagerService extends ActivityManagerNative
ProcessRecord pr = procs.get(i);
if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
- EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
pr.processName, pr.setAdj, "remove task");
pr.killedBackground = true;
Process.killProcessQuiet(pr.pid);
@@ -6442,7 +6439,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, true);
+ updateLruProcessLocked(cpr.proc, false);
}
}
@@ -6630,6 +6627,7 @@ public final class ActivityManagerService extends ActivityManagerNative
+ cpi.applicationInfo.uid + " for provider "
+ name + ": launching app became null");
EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
+ UserHandle.getUserId(cpi.applicationInfo.uid),
cpi.applicationInfo.packageName,
cpi.applicationInfo.uid, name);
return null;
@@ -7013,7 +7011,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (isolated) {
mIsolatedProcesses.put(app.uid, app);
}
- updateLruProcessLocked(app, true, true);
+ updateLruProcessLocked(app, true);
}
// This package really, really can not be stopped.
@@ -7499,7 +7497,7 @@ public final class ActivityManagerService extends ActivityManagerNative
int adj = proc.setAdj;
if (adj >= worstType && !proc.killedBackground) {
Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
- EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid,
proc.processName, adj, reason);
killed = true;
proc.killedBackground = true;
@@ -7535,8 +7533,8 @@ public final class ActivityManagerService extends ActivityManagerNative
final int adj = proc.setAdj;
if (adj > belowAdj && !proc.killedBackground) {
Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
- EventLog.writeEvent(
- EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
+ EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId,
+ proc.pid, proc.processName, adj, reason);
killed = true;
proc.killedBackground = true;
Process.killProcessQuiet(pid);
@@ -7953,7 +7951,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (app.pid > 0 && app.pid != MY_PID) {
handleAppCrashLocked(app);
Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
- EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
app.processName, app.setAdj, "user's request after error");
Process.killProcessQuiet(app.pid);
}
@@ -7978,7 +7976,7 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.w(TAG, "Process " + app.info.processName
+ " has crashed too many times: killing!");
EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
- app.info.processName, app.uid);
+ app.userId, app.info.processName, app.uid);
for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
if (r.app == app) {
@@ -7993,7 +7991,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// explicitly does so... but for persistent process, we really
// need to keep it running. If a persistent process is actually
// repeatedly crashing, then badness for everyone.
- EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
+ EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
app.info.processName);
if (!app.isolated) {
// XXX We don't have a way to mark isolated processes
@@ -8106,7 +8104,7 @@ public final class ActivityManagerService extends ActivityManagerNative
: (r == null ? "unknown" : r.processName);
EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
- processName,
+ UserHandle.getUserId(Binder.getCallingUid()), processName,
r == null ? -1 : r.info.flags,
crashInfo.exceptionClassName,
crashInfo.exceptionMessage,
@@ -8304,7 +8302,8 @@ public final class ActivityManagerService extends ActivityManagerNative
final String processName = app == null ? "system_server"
: (r == null ? "unknown" : r.processName);
- EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
+ EventLog.writeEvent(EventLogTags.AM_WTF,
+ UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
processName,
r == null ? -1 : r.info.flags,
tag, crashInfo.exceptionMessage);
@@ -10067,6 +10066,7 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.print(" ");
pw.print("oom: max="); pw.print(r.maxAdj);
pw.print(" hidden="); pw.print(r.hiddenAdj);
+ pw.print(" client="); pw.print(r.clientHiddenAdj);
pw.print(" empty="); pw.print(r.emptyAdj);
pw.print(" curRaw="); pw.print(r.curRawAdj);
pw.print(" setRaw="); pw.print(r.setRawAdj);
@@ -10591,7 +10591,7 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.i(TAG, "Kill " + capp.processName
+ " (pid " + capp.pid + "): provider " + cpr.info.name
+ " in dying process " + (proc != null ? proc.processName : "??"));
- EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid,
capp.processName, capp.setAdj, "dying provider "
+ cpr.name.toShortString());
Process.killProcessQuiet(capp.pid);
@@ -12466,7 +12466,7 @@ public final class ActivityManagerService extends ActivityManagerNative
return null;
}
- private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
+ private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj,
int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
if (mAdjSeq == app.adjSeq) {
// This adjustment has already been computed. If we are calling
@@ -12474,8 +12474,13 @@ public final class ActivityManagerService extends ActivityManagerNative
// an earlier hidden adjustment that isn't really for us... if
// so, use the new hidden adjustment.
if (!recursed && app.hidden) {
- app.curAdj = app.curRawAdj = app.nonStoppingAdj =
- app.hasActivities ? hiddenAdj : emptyAdj;
+ if (app.hasActivities) {
+ app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
+ } else if (app.hasClientActivities) {
+ app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj;
+ } else {
+ app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj;
+ }
}
return app.curRawAdj;
}
@@ -12491,6 +12496,7 @@ public final class ActivityManagerService extends ActivityManagerNative
app.adjTarget = null;
app.empty = false;
app.hidden = false;
+ app.hasClientActivities = false;
final int activitiesSize = app.activities.size();
@@ -12572,7 +12578,7 @@ public final class ActivityManagerService extends ActivityManagerNative
adj = hiddenAdj;
schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
app.hidden = true;
- app.adjType = "bg-activities";
+ app.adjType = "bg-act";
}
boolean hasStoppingActivities = false;
@@ -12614,11 +12620,16 @@ public final class ActivityManagerService extends ActivityManagerNative
}
if (adj == hiddenAdj && !app.hasActivities) {
- // Whoops, this process is completely empty as far as we know
- // at this point.
- adj = emptyAdj;
- app.empty = true;
- app.adjType = "bg-empty";
+ if (app.hasClientActivities) {
+ adj = clientHiddenAdj;
+ app.adjType = "bg-client-act";
+ } else {
+ // Whoops, this process is completely empty as far as we know
+ // at this point.
+ adj = emptyAdj;
+ app.empty = true;
+ app.adjType = "bg-empty";
+ }
}
if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
@@ -12626,13 +12637,13 @@ public final class ActivityManagerService extends ActivityManagerNative
// The user is aware of this app, so make it visible.
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
app.hidden = false;
- app.adjType = "foreground-service";
+ app.adjType = "fg-service";
schedGroup = Process.THREAD_GROUP_DEFAULT;
} else if (app.forcingToForeground != null) {
// The user is aware of this app, so make it visible.
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
app.hidden = false;
- app.adjType = "force-foreground";
+ app.adjType = "force-fg";
app.adjSource = app.forcingToForeground;
schedGroup = Process.THREAD_GROUP_DEFAULT;
}
@@ -12754,6 +12765,14 @@ public final class ActivityManagerService extends ActivityManagerNative
myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
}
}
+ int myClientHiddenAdj = clientHiddenAdj;
+ if (myClientHiddenAdj > client.clientHiddenAdj) {
+ if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
+ myClientHiddenAdj = client.clientHiddenAdj;
+ } else {
+ myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
+ }
+ }
int myEmptyAdj = emptyAdj;
if (myEmptyAdj > client.emptyAdj) {
if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
@@ -12763,7 +12782,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
clientAdj = computeOomAdjLocked(client, myHiddenAdj,
- myEmptyAdj, TOP_APP, true, doingAll);
+ myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
String adjType = null;
if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
// Not doing bind OOM management, so treat
@@ -12792,6 +12811,19 @@ 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 hidden process (with activities),
+ // we don't want the service it is connected to
+ // to go into the empty LRU and quickly get killed,
+ // because I'll we'll do is just end up restarting
+ // the service.
+ app.hasClientActivities |= client.hasActivities;
+ }
}
if (adj > clientAdj) {
// If this process has recently shown UI, and
@@ -12843,8 +12875,8 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
}
+ final ActivityRecord a = cr.activity;
if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
- ActivityRecord a = cr.activity;
if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
(a.visible || a.state == ActivityState.RESUMED
|| a.state == ActivityState.PAUSING)) {
@@ -12902,6 +12934,14 @@ public final class ActivityManagerService extends ActivityManagerNative
myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
}
}
+ int myClientHiddenAdj = clientHiddenAdj;
+ if (myClientHiddenAdj > client.clientHiddenAdj) {
+ if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) {
+ myClientHiddenAdj = client.clientHiddenAdj;
+ } else {
+ myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
+ }
+ }
int myEmptyAdj = emptyAdj;
if (myEmptyAdj > client.emptyAdj) {
if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
@@ -12911,7 +12951,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
- myEmptyAdj, TOP_APP, true, doingAll);
+ myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
if (adj > clientAdj) {
if (app.hasShownUi && app != mHomeProcess
&& clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
@@ -13301,7 +13341,7 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.w(TAG, "Excessive wake lock in " + app.processName
+ " (pid " + app.pid + "): held " + wtimeUsed
+ " during " + realtimeSince);
- EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
app.processName, app.setAdj, "excessive wake lock");
Process.killProcessQuiet(app.pid);
} else if (doCpuKills && uptimeSince > 0
@@ -13313,7 +13353,7 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.w(TAG, "Excessive CPU in " + app.processName
+ " (pid " + app.pid + "): used " + cputimeUsed
+ " during " + uptimeSince);
- EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
app.processName, app.setAdj, "excessive cpu");
Process.killProcessQuiet(app.pid);
} else {
@@ -13325,8 +13365,9 @@ public final class ActivityManagerService extends ActivityManagerNative
}
private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
- int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
+ int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
app.hiddenAdj = hiddenAdj;
+ app.clientHiddenAdj = clientHiddenAdj;
app.emptyAdj = emptyAdj;
if (app.thread == null) {
@@ -13337,7 +13378,7 @@ public final class ActivityManagerService extends ActivityManagerNative
boolean success = true;
- computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
+ computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll);
if (app.curRawAdj != app.setRawAdj) {
if (wasKeeping && !app.keeping) {
@@ -13374,7 +13415,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (app.waitingToKill != null &&
app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
- EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
app.processName, app.setAdj, app.waitingToKill);
app.killedBackground = true;
Process.killProcessQuiet(app.pid);
@@ -13424,8 +13465,8 @@ public final class ActivityManagerService extends ActivityManagerNative
mAdjSeq++;
- boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
- TOP_APP, false);
+ boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj,
+ app.emptyAdj, TOP_APP, false);
final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
&& app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
if (nowHidden != wasHidden) {
@@ -13439,6 +13480,7 @@ public final class ActivityManagerService extends ActivityManagerNative
final void updateOomAdjLocked() {
final ActivityRecord TOP_ACT = resumedAppLocked();
final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
+ final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME;
if (false) {
RuntimeException e = new RuntimeException();
@@ -13449,20 +13491,40 @@ public final class ActivityManagerService extends ActivityManagerNative
mAdjSeq++;
mNewNumServiceProcs = 0;
+ final int emptyProcessLimit;
+ final int hiddenProcessLimit;
+ if (mProcessLimit <= 0) {
+ emptyProcessLimit = hiddenProcessLimit = 0;
+ } else if (mProcessLimit == 1) {
+ emptyProcessLimit = 1;
+ hiddenProcessLimit = 0;
+ } else {
+ emptyProcessLimit = (mProcessLimit*2)/3;
+ hiddenProcessLimit = mProcessLimit - emptyProcessLimit;
+ }
+
// Let's determine how many processes we have running vs.
// how many slots we have for background processes; we may want
// to put multiple processes in a slot of there are enough of
// them.
int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
- ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
- int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
+ int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs;
+ if (numEmptyProcs > hiddenProcessLimit) {
+ // If there are more empty processes than our limit on hidden
+ // processes, then use the hidden process limit for the factor.
+ // This ensures that the really old empty processes get pushed
+ // down to the bottom, so if we are running low on memory we will
+ // have a better chance at keeping around more hidden processes
+ // instead of a gazillion empty processes.
+ numEmptyProcs = hiddenProcessLimit;
+ }
+ int emptyFactor = numEmptyProcs/numSlots;
if (emptyFactor < 1) emptyFactor = 1;
int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
if (hiddenFactor < 1) hiddenFactor = 1;
int stepHidden = 0;
int stepEmpty = 0;
- final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
- final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
int numHidden = 0;
int numEmpty = 0;
int numTrimming = 0;
@@ -13477,11 +13539,12 @@ public final class ActivityManagerService extends ActivityManagerNative
int nextHiddenAdj = curHiddenAdj+1;
int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
int nextEmptyAdj = curEmptyAdj+2;
+ int curClientHiddenAdj = curEmptyAdj;
while (i > 0) {
i--;
ProcessRecord app = mLruProcesses.get(i);
//Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
- updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
+ updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true);
if (!app.killedBackground) {
if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
// This process was assigned as a hidden process... step the
@@ -13496,17 +13559,31 @@ public final class ActivityManagerService extends ActivityManagerNative
if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
}
+ if (curClientHiddenAdj <= curHiddenAdj) {
+ curClientHiddenAdj = curHiddenAdj + 1;
+ if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
+ curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
+ }
+ }
}
}
numHidden++;
if (numHidden > hiddenProcessLimit) {
Slog.i(TAG, "No longer want " + app.processName
+ " (pid " + app.pid + "): hidden #" + numHidden);
- EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
app.processName, app.setAdj, "too many background");
app.killedBackground = true;
Process.killProcessQuiet(app.pid);
}
+ } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) {
+ // This process has a client that has activities. We will have
+ // given it the current hidden adj; here we will just leave it
+ // without stepping the hidden adj.
+ curClientHiddenAdj++;
+ if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
+ curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
+ }
} else {
if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
// This process was assigned as an empty process... step the
@@ -13525,15 +13602,28 @@ public final class ActivityManagerService extends ActivityManagerNative
} else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
mNumNonHiddenProcs++;
}
- if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
- numEmpty++;
- if (numEmpty > emptyProcessLimit) {
+ if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
+ && !app.hasClientActivities) {
+ if (numEmpty > ProcessList.TRIM_EMPTY_APPS
+ && app.lastActivityTime < oldTime) {
Slog.i(TAG, "No longer want " + app.processName
- + " (pid " + app.pid + "): empty #" + numEmpty);
- EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
- app.processName, app.setAdj, "too many background");
+ + " (pid " + app.pid + "): empty for "
+ + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime)
+ / 1000) + "s");
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
+ app.processName, app.setAdj, "old background process");
app.killedBackground = true;
Process.killProcessQuiet(app.pid);
+ } else {
+ numEmpty++;
+ if (numEmpty > emptyProcessLimit) {
+ Slog.i(TAG, "No longer want " + app.processName
+ + " (pid " + app.pid + "): empty #" + numEmpty);
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
+ app.processName, app.setAdj, "too many background");
+ app.killedBackground = true;
+ Process.killProcessQuiet(app.pid);
+ }
}
}
}
@@ -13546,7 +13636,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// left sitting around after no longer needed.
Slog.i(TAG, "Isolated process " + app.processName
+ " (pid " + app.pid + ") no longer needed");
- EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
app.processName, app.setAdj, "isolated not needed");
app.killedBackground = true;
Process.killProcessQuiet(app.pid);
@@ -13567,8 +13657,8 @@ public final class ActivityManagerService extends ActivityManagerNative
// are managing to keep around is less than half the maximum we desire;
// if we are keeping a good number around, we'll let them use whatever
// memory they want.
- if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
- && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
+ if (numHidden <= ProcessList.TRIM_HIDDEN_APPS
+ && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
final int numHiddenAndEmpty = numHidden + numEmpty;
final int N = mLruProcesses.size();
int factor = numTrimming/3;
@@ -13578,9 +13668,9 @@ public final class ActivityManagerService extends ActivityManagerNative
if (factor < minFactor) factor = minFactor;
int step = 0;
int fgTrimLevel;
- if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
+ if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
- } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
+ } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
} else {
fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
@@ -13700,7 +13790,7 @@ public final class ActivityManagerService extends ActivityManagerNative
+ (app.thread != null ? app.thread.asBinder() : null)
+ ")\n");
if (app.pid > 0 && app.pid != MY_PID) {
- EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
app.processName, app.setAdj, "empty");
Process.killProcessQuiet(app.pid);
} else {
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 7ff5748..6cd86fd 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -746,8 +746,8 @@ final class ActivityRecord {
final long totalTime = stack.mInitialStartTime != 0
? (curTime - stack.mInitialStartTime) : thisTime;
if (ActivityManagerService.SHOW_ACTIVITY_START_TIME) {
- EventLog.writeEvent(EventLogTags.ACTIVITY_LAUNCH_TIME,
- System.identityHashCode(this), shortComponentName,
+ EventLog.writeEvent(EventLogTags.AM_ACTIVITY_LAUNCH_TIME,
+ userId, System.identityHashCode(this), shortComponentName,
thisTime, totalTime);
StringBuilder sb = service.mStringBuilder;
sb.setLength(0);
@@ -923,6 +923,8 @@ final class ActivityRecord {
StringBuilder sb = new StringBuilder(128);
sb.append("ActivityRecord{");
sb.append(Integer.toHexString(System.identityHashCode(this)));
+ sb.append(" u");
+ sb.append(userId);
sb.append(' ');
sb.append(intent.getComponent().flattenToShortString());
sb.append('}');
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 1707ff0..2d445274 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -638,7 +638,7 @@ final class ActivityStack {
if (idx < 0) {
app.activities.add(r);
}
- mService.updateLruProcessLocked(app, true, true);
+ mService.updateLruProcessLocked(app, true);
try {
if (app.thread == null) {
@@ -656,7 +656,7 @@ final class ActivityStack {
+ " andResume=" + andResume);
if (andResume) {
EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
- System.identityHashCode(r),
+ r.userId, System.identityHashCode(r),
r.task.taskId, r.shortComponentName);
}
if (r.isHomeActivity) {
@@ -951,7 +951,7 @@ final class ActivityStack {
if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending pause: " + prev);
try {
EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
- System.identityHashCode(prev),
+ prev.userId, System.identityHashCode(prev),
prev.shortComponentName);
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving, prev.configChangeFlags);
@@ -1040,7 +1040,7 @@ final class ActivityStack {
completePauseLocked();
} else {
EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
- System.identityHashCode(r), r.shortComponentName,
+ r.userId, System.identityHashCode(r), r.shortComponentName,
mPausingActivity != null
? mPausingActivity.shortComponentName : "(none)");
}
@@ -1505,7 +1505,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, false);
}
startPausingLocked(userLeaving, false);
return true;
@@ -1641,7 +1641,7 @@ final class ActivityStack {
if (mMainStack) {
mService.addRecentTaskLocked(next.task);
}
- mService.updateLruProcessLocked(next.app, true, true);
+ mService.updateLruProcessLocked(next.app, true);
updateLRUListLocked(next);
// Have the window manager re-evaluate the orientation of
@@ -1699,7 +1699,7 @@ final class ActivityStack {
}
EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY,
- System.identityHashCode(next),
+ next.userId, System.identityHashCode(next),
next.task.taskId, next.shortComponentName);
next.sleeping = false;
@@ -2967,7 +2967,7 @@ final class ActivityStack {
intent, r.getUriPermissionsLocked());
if (newTask) {
- EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.task.taskId);
+ EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
}
logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
startActivityLocked(r, newTask, doResume, keepCurTransition, options);
@@ -3700,7 +3700,7 @@ final class ActivityStack {
r.makeFinishing();
EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
- System.identityHashCode(r),
+ r.userId, System.identityHashCode(r),
r.task.taskId, r.shortComponentName, reason);
if (index < (mHistory.size()-1)) {
ActivityRecord next = mHistory.get(index+1);
@@ -3996,7 +3996,7 @@ final class ActivityStack {
TAG, "Removing activity from " + reason + ": token=" + r
+ ", app=" + (r.app != null ? r.app.processName : "(null)"));
EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY,
- System.identityHashCode(r),
+ r.userId, System.identityHashCode(r),
r.task.taskId, r.shortComponentName, reason);
boolean removedFromHistory = false;
@@ -4228,7 +4228,7 @@ final class ActivityStack {
}
finishTaskMoveLocked(task);
- EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, task);
+ EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, task);
}
private final void finishTaskMoveLocked(int task) {
@@ -4448,7 +4448,7 @@ final class ActivityStack {
private final void logStartActivity(int tag, ActivityRecord r,
TaskRecord task) {
EventLog.writeEvent(tag,
- System.identityHashCode(r), task.taskId,
+ r.userId, System.identityHashCode(r), task.taskId,
r.shortComponentName, r.intent.getAction(),
r.intent.getType(), r.intent.getDataString(),
r.intent.getFlags());
@@ -4590,7 +4590,7 @@ final class ActivityStack {
+ " with results=" + results + " newIntents=" + newIntents
+ " andResume=" + andResume);
EventLog.writeEvent(andResume ? EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY
- : EventLogTags.AM_RELAUNCH_ACTIVITY, System.identityHashCode(r),
+ : EventLogTags.AM_RELAUNCH_ACTIVITY, r.userId, System.identityHashCode(r),
r.task.taskId, r.shortComponentName);
r.startFreezingScreenLocked(r.app, 0);
diff --git a/services/java/com/android/server/am/BroadcastFilter.java b/services/java/com/android/server/am/BroadcastFilter.java
index 07440b5..c631b6e 100644
--- a/services/java/com/android/server/am/BroadcastFilter.java
+++ b/services/java/com/android/server/am/BroadcastFilter.java
@@ -64,6 +64,8 @@ class BroadcastFilter extends IntentFilter {
StringBuilder sb = new StringBuilder();
sb.append("BroadcastFilter{");
sb.append(Integer.toHexString(System.identityHashCode(this)));
+ sb.append(" u");
+ sb.append(owningUserId);
sb.append(' ');
sb.append(receiverList);
sb.append('}');
diff --git a/services/java/com/android/server/am/BroadcastQueue.java b/services/java/com/android/server/am/BroadcastQueue.java
index b0af081..9f27994 100644
--- a/services/java/com/android/server/am/BroadcastQueue.java
+++ b/services/java/com/android/server/am/BroadcastQueue.java
@@ -209,7 +209,7 @@ public class BroadcastQueue {
r.receiver = app.thread.asBinder();
r.curApp = app;
app.curReceiver = r;
- mService.updateLruProcessLocked(app, true, true);
+ mService.updateLruProcessLocked(app, true);
// Tell the application to launch this receiver.
r.intent.setComponent(r.curComponent);
@@ -930,22 +930,22 @@ public class BroadcastQueue {
if (curReceiver instanceof BroadcastFilter) {
BroadcastFilter bf = (BroadcastFilter) curReceiver;
EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
- System.identityHashCode(r),
+ bf.owningUserId, System.identityHashCode(r),
r.intent.getAction(),
r.nextReceiver - 1,
System.identityHashCode(bf));
} else {
+ ResolveInfo ri = (ResolveInfo)curReceiver;
EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
- System.identityHashCode(r),
- r.intent.getAction(),
- r.nextReceiver - 1,
- ((ResolveInfo)curReceiver).toString());
+ UserHandle.getUserId(ri.activityInfo.applicationInfo.uid),
+ System.identityHashCode(r), r.intent.getAction(),
+ r.nextReceiver - 1, ri.toString());
}
} else {
Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
+ r);
EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
- System.identityHashCode(r),
+ -1, System.identityHashCode(r),
r.intent.getAction(),
r.nextReceiver,
"NONE");
diff --git a/services/java/com/android/server/am/BroadcastRecord.java b/services/java/com/android/server/am/BroadcastRecord.java
index ca6d5f7..85ec328 100644
--- a/services/java/com/android/server/am/BroadcastRecord.java
+++ b/services/java/com/android/server/am/BroadcastRecord.java
@@ -194,6 +194,6 @@ class BroadcastRecord extends Binder {
public String toString() {
return "BroadcastRecord{"
+ Integer.toHexString(System.identityHashCode(this))
- + " " + intent.getAction() + "}";
+ + " u" + userId + " " + intent.getAction() + "}";
}
}
diff --git a/services/java/com/android/server/am/ConnectionRecord.java b/services/java/com/android/server/am/ConnectionRecord.java
index 5b3ff8d..4ed3c31 100644
--- a/services/java/com/android/server/am/ConnectionRecord.java
+++ b/services/java/com/android/server/am/ConnectionRecord.java
@@ -62,6 +62,8 @@ class ConnectionRecord {
StringBuilder sb = new StringBuilder(128);
sb.append("ConnectionRecord{");
sb.append(Integer.toHexString(System.identityHashCode(this)));
+ sb.append(" u");
+ sb.append(binding.client.userId);
sb.append(' ');
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
sb.append("CR ");
@@ -70,7 +72,7 @@ class ConnectionRecord {
sb.append("DBG ");
}
if ((flags&Context.BIND_NOT_FOREGROUND) != 0) {
- sb.append("NOTFG ");
+ sb.append("!FG ");
}
if ((flags&Context.BIND_ABOVE_CLIENT) != 0) {
sb.append("ABCLT ");
@@ -88,7 +90,10 @@ class ConnectionRecord {
sb.append("ACT ");
}
if ((flags&Context.BIND_NOT_VISIBLE) != 0) {
- sb.append("NOTVIS ");
+ sb.append("!VIS ");
+ }
+ if ((flags&Context.BIND_VISIBLE) != 0) {
+ sb.append("VIS ");
}
if (serviceDead) {
sb.append("DEAD ");
diff --git a/services/java/com/android/server/am/ContentProviderRecord.java b/services/java/com/android/server/am/ContentProviderRecord.java
index de306b5..8fb6a93 100644
--- a/services/java/com/android/server/am/ContentProviderRecord.java
+++ b/services/java/com/android/server/am/ContentProviderRecord.java
@@ -25,6 +25,7 @@ import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
import android.os.Process;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.util.Slog;
import java.io.PrintWriter;
@@ -199,6 +200,8 @@ class ContentProviderRecord {
StringBuilder sb = new StringBuilder(128);
sb.append("ContentProviderRecord{");
sb.append(Integer.toHexString(System.identityHashCode(this)));
+ sb.append(" u");
+ sb.append(UserHandle.getUserId(uid));
sb.append(' ');
sb.append(name.flattenToShortString());
sb.append('}');
diff --git a/services/java/com/android/server/am/EventLogTags.logtags b/services/java/com/android/server/am/EventLogTags.logtags
index a579f44..6ee7507 100644
--- a/services/java/com/android/server/am/EventLogTags.logtags
+++ b/services/java/com/android/server/am/EventLogTags.logtags
@@ -14,72 +14,72 @@ option java_package com.android.server.am
# google3/googledata/wireless/android/provisioning/gservices.config !!
#
# An activity is being finished:
-30001 am_finish_activity (Token|1|5),(Task ID|1|5),(Component Name|3),(Reason|3)
+30001 am_finish_activity (User|1|5),(Token|1|5),(Task ID|1|5),(Component Name|3),(Reason|3)
# A task is being brought to the front of the screen:
-30002 am_task_to_front (Task|1|5)
+30002 am_task_to_front (User|1|5),(Task|1|5)
# An existing activity is being given a new intent:
-30003 am_new_intent (Token|1|5),(Task ID|1|5),(Component Name|3),(Action|3),(MIME Type|3),(URI|3),(Flags|1|5)
+30003 am_new_intent (User|1|5),(Token|1|5),(Task ID|1|5),(Component Name|3),(Action|3),(MIME Type|3),(URI|3),(Flags|1|5)
# A new task is being created:
-30004 am_create_task (Task ID|1|5)
+30004 am_create_task (User|1|5),(Task ID|1|5)
# A new activity is being created in an existing task:
-30005 am_create_activity (Token|1|5),(Task ID|1|5),(Component Name|3),(Action|3),(MIME Type|3),(URI|3),(Flags|1|5)
+30005 am_create_activity (User|1|5),(Token|1|5),(Task ID|1|5),(Component Name|3),(Action|3),(MIME Type|3),(URI|3),(Flags|1|5)
# An activity has been resumed into the foreground but was not already running:
-30006 am_restart_activity (Token|1|5),(Task ID|1|5),(Component Name|3)
+30006 am_restart_activity (User|1|5),(Token|1|5),(Task ID|1|5),(Component Name|3)
# An activity has been resumed and is now in the foreground:
-30007 am_resume_activity (Token|1|5),(Task ID|1|5),(Component Name|3)
+30007 am_resume_activity (User|1|5),(Token|1|5),(Task ID|1|5),(Component Name|3)
# Application Not Responding
-30008 am_anr (pid|1|5),(Package Name|3),(Flags|1|5),(reason|3)
+30008 am_anr (User|1|5),(pid|1|5),(Package Name|3),(Flags|1|5),(reason|3)
# Activity launch time
-30009 activity_launch_time (Token|1|5),(Component Name|3),(time|2|3)
+30009 am_activity_launch_time (User|1|5),(Token|1|5),(Component Name|3),(time|2|3)
# Application process bound to work
-30010 am_proc_bound (PID|1|5),(Process Name|3)
+30010 am_proc_bound (User|1|5),(PID|1|5),(Process Name|3)
# Application process died
-30011 am_proc_died (PID|1|5),(Process Name|3)
+30011 am_proc_died (User|1|5),(PID|1|5),(Process Name|3)
# The Activity Manager failed to pause the given activity.
-30012 am_failed_to_pause (Token|1|5),(Wanting to pause|3),(Currently pausing|3)
+30012 am_failed_to_pause (User|1|5),(Token|1|5),(Wanting to pause|3),(Currently pausing|3)
# Attempting to pause the current activity
-30013 am_pause_activity (Token|1|5),(Component Name|3)
+30013 am_pause_activity (User|1|5),(Token|1|5),(Component Name|3)
# Application process has been started
-30014 am_proc_start (PID|1|5),(UID|1|5),(Process Name|3),(Type|3),(Component|3)
+30014 am_proc_start (User|1|5),(PID|1|5),(UID|1|5),(Process Name|3),(Type|3),(Component|3)
# An application process has been marked as bad
-30015 am_proc_bad (UID|1|5),(Process Name|3)
+30015 am_proc_bad (User|1|5),(UID|1|5),(Process Name|3)
# An application process that was bad is now marked as good
-30016 am_proc_good (UID|1|5),(Process Name|3)
+30016 am_proc_good (User|1|5),(UID|1|5),(Process Name|3)
# Reporting to applications that memory is low
30017 am_low_memory (Num Processes|1|1)
# An activity is being destroyed:
-30018 am_destroy_activity (Token|1|5),(Task ID|1|5),(Component Name|3),(Reason|3)
+30018 am_destroy_activity (User|1|5),(Token|1|5),(Task ID|1|5),(Component Name|3),(Reason|3)
# An activity has been relaunched, resumed, and is now in the foreground:
-30019 am_relaunch_resume_activity (Token|1|5),(Task ID|1|5),(Component Name|3)
+30019 am_relaunch_resume_activity (User|1|5),(Token|1|5),(Task ID|1|5),(Component Name|3)
# An activity has been relaunched:
-30020 am_relaunch_activity (Token|1|5),(Task ID|1|5),(Component Name|3)
+30020 am_relaunch_activity (User|1|5),(Token|1|5),(Task ID|1|5),(Component Name|3)
# The activity's onPause has been called.
-30021 am_on_paused_called (Component Name|3)
+30021 am_on_paused_called (User|1|5),(Component Name|3)
# The activity's onResume has been called.
-30022 am_on_resume_called (Component Name|3)
+30022 am_on_resume_called (User|1|5),(Component Name|3)
# Kill a process to reclaim memory.
-30023 am_kill (PID|1|5),(Process Name|3),(OomAdj|1|5),(Reason|3)
+30023 am_kill (User|1|5),(PID|1|5),(Process Name|3),(OomAdj|1|5),(Reason|3)
# Discard an undelivered serialized broadcast (timeout/ANR/crash)
-30024 am_broadcast_discard_filter (Broadcast|1|5),(Action|3),(Receiver Number|1|1),(BroadcastFilter|1|5)
-30025 am_broadcast_discard_app (Broadcast|1|5),(Action|3),(Receiver Number|1|1),(App|3)
+30024 am_broadcast_discard_filter (User|1|5),(Broadcast|1|5),(Action|3),(Receiver Number|1|1),(BroadcastFilter|1|5)
+30025 am_broadcast_discard_app (User|1|5),(Broadcast|1|5),(Action|3),(Receiver Number|1|1),(App|3)
# A service is being created
-30030 am_create_service (Service Record|1|5),(Name|3),(Intent|3),(PID|1|5)
+30030 am_create_service (User|1|5),(Service Record|1|5),(Name|3),(Intent|3),(PID|1|5)
# A service is being destroyed
-30031 am_destroy_service (Service Record|1|5),(Name|3),(PID|1|5)
+30031 am_destroy_service (User|1|5),(Service Record|1|5),(Name|3),(PID|1|5)
# A process has crashed too many times, it is being cleared
-30032 am_process_crashed_too_much (Name|3),(PID|1|5)
+30032 am_process_crashed_too_much (User|1|5),(Name|3),(PID|1|5)
# An unknown process is trying to attach to the activity manager
30033 am_drop_process (PID|1|5)
# A service has crashed too many times, it is being stopped
-30034 am_service_crashed_too_much (Crash Count|1|1),(Component Name|3),(PID|1|5)
+30034 am_service_crashed_too_much (User|1|5),(Crash Count|1|1),(Component Name|3),(PID|1|5)
# A service is going to be restarted after its process went away
-30035 am_schedule_service_restart (Component Name|3),(Time|2|3)
+30035 am_schedule_service_restart (User|1|5),(Component Name|3),(Time|2|3)
# A client was waiting for a content provider, but its process was lost
-30036 am_provider_lost_process (Package Name|3),(UID|1|5),(Name|3)
+30036 am_provider_lost_process (User|1|5),(Package Name|3),(UID|1|5),(Name|3)
# The activity manager gave up on a new process taking too long to start
-30037 am_process_start_timeout (PID|1|5),(UID|1|5),(Process Name|3)
+30037 am_process_start_timeout (User|1|5),(PID|1|5),(UID|1|5),(Process Name|3)
# Unhandled exception
-30039 am_crash (PID|1|5),(Process Name|3),(Flags|1|5),(Exception|3),(Message|3),(File|3),(Line|1|5)
+30039 am_crash (User|1|5),(PID|1|5),(Process Name|3),(Flags|1|5),(Exception|3),(Message|3),(File|3),(Line|1|5)
# Log.wtf() called
-30040 am_wtf (PID|1|5),(Process Name|3),(Flags|1|5),(Tag|3),(Message|3)
+30040 am_wtf (User|1|5),(PID|1|5),(Process Name|3),(Flags|1|5),(Tag|3),(Message|3)
diff --git a/services/java/com/android/server/am/ProcessList.java b/services/java/com/android/server/am/ProcessList.java
index afc060e..9e25e30 100644
--- a/services/java/com/android/server/am/ProcessList.java
+++ b/services/java/com/android/server/am/ProcessList.java
@@ -101,7 +101,24 @@ class ProcessList {
// The maximum number of hidden processes we will keep around before
// killing them; this is just a control to not let us go too crazy with
// keeping around processes on devices with large amounts of RAM.
- static final int MAX_HIDDEN_APPS = 15;
+ static final int MAX_HIDDEN_APPS = 24;
+
+ // We allow empty processes to stick around for at most 30 minutes.
+ static final long MAX_EMPTY_TIME = 30*60*1000;
+
+ // The number of hidden at which we don't consider it necessary to do
+ // memory trimming.
+ static final int TRIM_HIDDEN_APPS = 3;
+
+ // The number of empty apps at which we don't consider it necessary to do
+ // memory trimming.
+ static final int TRIM_EMPTY_APPS = 3;
+
+ // Threshold of number of hidden+empty where we consider memory critical.
+ static final int TRIM_CRITICAL_THRESHOLD = 3;
+
+ // Threshold of number of hidden+empty where we consider memory critical.
+ static final int TRIM_LOW_THRESHOLD = 5;
// We put empty content processes after any hidden processes that have
// been idle for less than 15 seconds.
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index d372422..652fdb5 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -61,6 +61,7 @@ class ProcessRecord {
long lruWeight; // Weight for ordering in LRU list
int maxAdj; // Maximum OOM adjustment for this process
int hiddenAdj; // If hidden, this is the adjustment to use
+ int clientHiddenAdj; // If empty but hidden client, this is the adjustment to use
int emptyAdj; // If empty, this is the adjustment to use
int curRawAdj; // Current OOM unlimited adjustment for this process
int setRawAdj; // Last set OOM unlimited adjustment for this process
@@ -75,6 +76,7 @@ class ProcessRecord {
boolean keeping; // Actively running code so don't kill due to that?
boolean setIsForeground; // Running foreground UI when last set?
boolean hasActivities; // Are there any activities running in this process?
+ boolean hasClientActivities; // Are there any client services with activities?
boolean foregroundServices; // Running any services that are foreground?
boolean foregroundActivities; // Running any activities that are foreground?
boolean systemNoUi; // This is a system process, but not currently showing UI.
@@ -188,8 +190,7 @@ class ProcessRecord {
instrumentationInfo.dump(new PrintWriterPrinter(pw), prefix + " ");
}
}
- pw.print(prefix); pw.print("thread="); pw.print(thread);
- pw.print(" curReceiver="); pw.println(curReceiver);
+ pw.print(prefix); pw.print("thread="); pw.println(thread);
pw.print(prefix); pw.print("pid="); pw.print(pid); pw.print(" starting=");
pw.print(starting); pw.print(" lastPss="); pw.println(lastPss);
pw.print(prefix); pw.print("lastActivityTime=");
@@ -201,6 +202,7 @@ class ProcessRecord {
pw.print(" empty="); pw.println(empty);
pw.print(prefix); pw.print("oom: max="); pw.print(maxAdj);
pw.print(" hidden="); pw.print(hiddenAdj);
+ pw.print(" client="); pw.print(clientHiddenAdj);
pw.print(" empty="); pw.print(emptyAdj);
pw.print(" curRaw="); pw.print(curRawAdj);
pw.print(" setRaw="); pw.print(setRawAdj);
@@ -211,18 +213,27 @@ class ProcessRecord {
pw.print(" setSchedGroup="); pw.print(setSchedGroup);
pw.print(" systemNoUi="); pw.print(systemNoUi);
pw.print(" trimMemoryLevel="); pw.println(trimMemoryLevel);
- pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi);
- pw.print(" pendingUiClean="); pw.print(pendingUiClean);
- pw.print(" hasAboveClient="); pw.println(hasAboveClient);
- pw.print(prefix); pw.print("setIsForeground="); pw.print(setIsForeground);
- pw.print(" foregroundServices="); pw.print(foregroundServices);
- pw.print(" forcingToForeground="); pw.println(forcingToForeground);
- pw.print(prefix); pw.print("persistent="); pw.print(persistent);
- pw.print(" removed="); pw.print(removed);
- pw.print(" hasActivities="); pw.print(hasActivities);
- pw.print(" foregroundActivities="); pw.println(foregroundActivities);
pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq);
pw.print(" lruSeq="); pw.println(lruSeq);
+ if (hasShownUi || pendingUiClean || hasAboveClient) {
+ pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi);
+ pw.print(" pendingUiClean="); pw.print(pendingUiClean);
+ pw.print(" hasAboveClient="); pw.println(hasAboveClient);
+ }
+ if (setIsForeground || foregroundServices || forcingToForeground != null) {
+ pw.print(prefix); pw.print("setIsForeground="); pw.print(setIsForeground);
+ pw.print(" foregroundServices="); pw.print(foregroundServices);
+ pw.print(" forcingToForeground="); pw.println(forcingToForeground);
+ }
+ if (persistent || removed) {
+ 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);
+ pw.print(" foregroundActivities="); pw.println(foregroundActivities);
+ }
if (!keeping) {
long wtime;
synchronized (batteryStats.getBatteryStats()) {
@@ -231,10 +242,10 @@ class ProcessRecord {
}
long timeUsed = wtime - lastWakeTime;
pw.print(prefix); pw.print("lastWakeTime="); pw.print(lastWakeTime);
- pw.print(" time used=");
+ pw.print(" timeUsed=");
TimeUtils.formatDuration(timeUsed, pw); pw.println("");
pw.print(prefix); pw.print("lastCpuTime="); pw.print(lastCpuTime);
- pw.print(" time used=");
+ pw.print(" timeUsed=");
TimeUtils.formatDuration(curCpuTime-lastCpuTime, pw); pw.println("");
}
pw.print(prefix); pw.print("lastRequestedGc=");
@@ -299,6 +310,9 @@ class ProcessRecord {
pw.print(prefix); pw.print(" - "); pw.println(conProviders.get(i).toShortString());
}
}
+ if (curReceiver != null) {
+ pw.print(prefix); pw.print("curReceiver="); pw.println(curReceiver);
+ }
if (receivers.size() > 0) {
pw.print(prefix); pw.println("Receivers:");
for (ReceiverList rl : receivers) {
@@ -318,7 +332,7 @@ class ProcessRecord {
pkgList.add(_info.packageName);
thread = _thread;
maxAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
- hiddenAdj = emptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
+ hiddenAdj = clientHiddenAdj = emptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
curRawAdj = setRawAdj = -100;
curAdj = setAdj = -100;
persistent = false;
diff --git a/services/java/com/android/server/am/ServiceRecord.java b/services/java/com/android/server/am/ServiceRecord.java
index 7055fdc..84e824a 100644
--- a/services/java/com/android/server/am/ServiceRecord.java
+++ b/services/java/com/android/server/am/ServiceRecord.java
@@ -425,6 +425,7 @@ class ServiceRecord extends Binder {
StringBuilder sb = new StringBuilder(128);
sb.append("ServiceRecord{")
.append(Integer.toHexString(System.identityHashCode(this)))
+ .append(" u").append(userId)
.append(' ').append(shortName).append('}');
return stringName = sb.toString();
}