diff options
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(); } |