@@ -176,6 +176,7 @@ public final class ActivityManagerService extends ActivityManagerNative
176176 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
177177 static final boolean DEBUG_VISBILITY = localLOGV || false;
178178 static final boolean DEBUG_PROCESSES = localLOGV || false;
179+ static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
179180 static final boolean DEBUG_PROVIDER = localLOGV || false;
180181 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
181182 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
@@ -764,8 +765,24 @@ private class Identity {
764765 boolean mAutoStopProfiler = false;
765766 String mOpenGlTraceApp = null;
766767
768+ static class ProcessChangeItem {
769+ static final int CHANGE_ACTIVITIES = 1<<0;
770+ static final int CHANGE_IMPORTANCE= 1<<1;
771+ int changes;
772+ int uid;
773+ int pid;
774+ int importance;
775+ boolean foregroundActivities;
776+ }
777+
767778 final RemoteCallbackList<IProcessObserver> mProcessObservers
768779 = new RemoteCallbackList<IProcessObserver>();
780+ ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
781+
782+ final ArrayList<ProcessChangeItem> mPendingProcessChanges
783+ = new ArrayList<ProcessChangeItem>();
784+ final ArrayList<ProcessChangeItem> mAvailProcessChanges
785+ = new ArrayList<ProcessChangeItem>();
769786
770787 /**
771788 * Callback of last caller to {@link #requestPss}.
@@ -855,7 +872,7 @@ public void binderDied() {
855872 static final int CLEAR_DNS_CACHE = 28;
856873 static final int UPDATE_HTTP_PROXY = 29;
857874 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
858- static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
875+ static final int DISPATCH_PROCESSES_CHANGED = 31;
859876 static final int DISPATCH_PROCESS_DIED = 32;
860877 static final int REPORT_MEM_USAGE = 33;
861878
@@ -1195,11 +1212,8 @@ public void handleMessage(Message msg) {
11951212 }
11961213 break;
11971214 }
1198- case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
1199- final int pid = msg.arg1;
1200- final int uid = msg.arg2;
1201- final boolean foregroundActivities = (Boolean) msg.obj;
1202- dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
1215+ case DISPATCH_PROCESSES_CHANGED: {
1216+ dispatchProcessesChanged();
12031217 break;
12041218 }
12051219 case DISPATCH_PROCESS_DIED: {
@@ -2260,19 +2274,43 @@ public void setPackageAskScreenCompat(String packageName, boolean ask) {
22602274
22612275 void reportResumedActivityLocked(ActivityRecord r) {
22622276 //Slog.i(TAG, "**** REPORT RESUME: " + r);
2263-
2264- final int identHash = System.identityHashCode(r);
22652277 updateUsageStats(r, true);
22662278 }
22672279
2268- private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2280+ private void dispatchProcessesChanged() {
2281+ int N;
2282+ synchronized (this) {
2283+ N = mPendingProcessChanges.size();
2284+ if (mActiveProcessChanges.length < N) {
2285+ mActiveProcessChanges = new ProcessChangeItem[N];
2286+ }
2287+ mPendingProcessChanges.toArray(mActiveProcessChanges);
2288+ mAvailProcessChanges.addAll(mPendingProcessChanges);
2289+ mPendingProcessChanges.clear();
2290+ if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2291+ }
22692292 int i = mProcessObservers.beginBroadcast();
22702293 while (i > 0) {
22712294 i--;
22722295 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
22732296 if (observer != null) {
22742297 try {
2275- observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2298+ for (int j=0; j<N; j++) {
2299+ ProcessChangeItem item = mActiveProcessChanges[j];
2300+ if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2301+ if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2302+ + item.pid + " uid=" + item.uid + ": "
2303+ + item.foregroundActivities);
2304+ observer.onForegroundActivitiesChanged(item.pid, item.uid,
2305+ item.foregroundActivities);
2306+ }
2307+ if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2308+ if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2309+ + item.pid + " uid=" + item.uid + ": " + item.importance);
2310+ observer.onImportanceChanged(item.pid, item.uid,
2311+ item.importance);
2312+ }
2313+ }
22762314 } catch (RemoteException e) {
22772315 }
22782316 }
@@ -10802,6 +10840,13 @@ private final void cleanUpApplicationRecordLocked(ProcessRecord app,
1080210840 }
1080310841 }
1080410842
10843+ for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10844+ ProcessChangeItem item = mPendingProcessChanges.get(i);
10845+ if (item.pid == app.pid) {
10846+ mPendingProcessChanges.remove(i);
10847+ mAvailProcessChanges.add(item);
10848+ }
10849+ }
1080510850 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
1080610851
1080710852 // If the caller is restarting this app, then leave it in its
@@ -13734,28 +13779,29 @@ private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
1373413779 return (app.curAdj=app.maxAdj);
1373513780 }
1373613781
13737- final boolean hadForegroundActivities = app.foregroundActivities;
13738-
13739- app.foregroundActivities = false;
1374013782 app.keeping = false;
1374113783 app.systemNoUi = false;
1374213784
1374313785 // Determine the importance of the process, starting with most
1374413786 // important to least, and assign an appropriate OOM adjustment.
1374513787 int adj;
1374613788 int schedGroup;
13789+ boolean foregroundActivities = false;
13790+ boolean interesting = false;
1374713791 BroadcastQueue queue;
1374813792 if (app == TOP_APP) {
1374913793 // The last app on the list is the foreground app.
1375013794 adj = ProcessList.FOREGROUND_APP_ADJ;
1375113795 schedGroup = Process.THREAD_GROUP_DEFAULT;
1375213796 app.adjType = "top-activity";
13753- app.foregroundActivities = true;
13797+ foregroundActivities = true;
13798+ interesting = true;
1375413799 } else if (app.instrumentationClass != null) {
1375513800 // Don't want to kill running instrumentation.
1375613801 adj = ProcessList.FOREGROUND_APP_ADJ;
1375713802 schedGroup = Process.THREAD_GROUP_DEFAULT;
1375813803 app.adjType = "instrumentation";
13804+ interesting = true;
1375913805 } else if ((queue = isReceivingBroadcast(app)) != null) {
1376013806 // An app that is currently receiving a broadcast also
1376113807 // counts as being in the foreground for OOM killer purposes.
@@ -13791,7 +13837,7 @@ private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
1379113837 boolean hasStoppingActivities = false;
1379213838
1379313839 // Examine all activities if not already foreground.
13794- if (!app. foregroundActivities && activitiesSize > 0) {
13840+ if (!foregroundActivities && activitiesSize > 0) {
1379513841 for (int j = 0; j < activitiesSize; j++) {
1379613842 final ActivityRecord r = app.activities.get(j);
1379713843 if (r.visible) {
@@ -13802,21 +13848,21 @@ private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
1380213848 }
1380313849 schedGroup = Process.THREAD_GROUP_DEFAULT;
1380413850 app.hidden = false;
13805- app. foregroundActivities = true;
13851+ foregroundActivities = true;
1380613852 break;
1380713853 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
1380813854 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
1380913855 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
1381013856 app.adjType = "pausing";
1381113857 }
1381213858 app.hidden = false;
13813- app. foregroundActivities = true;
13859+ foregroundActivities = true;
1381413860 } else if (r.state == ActivityState.STOPPING) {
1381513861 // We will apply the actual adjustment later, because
1381613862 // we want to allow this process to immediately go through
1381713863 // any memory trimming that is in effect.
1381813864 app.hidden = false;
13819- app. foregroundActivities = true;
13865+ foregroundActivities = true;
1382013866 hasStoppingActivities = true;
1382113867 }
1382213868 }
@@ -13839,6 +13885,10 @@ private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
1383913885 }
1384013886 }
1384113887
13888+ if (app.foregroundServices) {
13889+ interesting = true;
13890+ }
13891+
1384213892 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
1384313893 // We don't want to kill the current heavy-weight process.
1384413894 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
@@ -14188,12 +14238,84 @@ private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
1418814238 }
1418914239 }
1419014240
14191- app.curAdj = adj;
14192- app.curSchedGroup = schedGroup;
14241+ int importance = app.memImportance;
14242+ if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14243+ app.curAdj = adj;
14244+ app.curSchedGroup = schedGroup;
14245+ if (!interesting) {
14246+ // For this reporting, if there is not something explicitly
14247+ // interesting in this process then we will push it to the
14248+ // background importance.
14249+ importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14250+ } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
14251+ importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14252+ } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14253+ importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14254+ } else if (adj >= ProcessList.HOME_APP_ADJ) {
14255+ importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14256+ } else if (adj >= ProcessList.SERVICE_ADJ) {
14257+ importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14258+ } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14259+ importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14260+ } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14261+ importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14262+ } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14263+ importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14264+ } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14265+ importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14266+ } else {
14267+ importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14268+ }
14269+ }
1419314270
14194- if (hadForegroundActivities != app.foregroundActivities) {
14195- mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
14196- app.foregroundActivities).sendToTarget();
14271+ int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14272+ if (foregroundActivities != app.foregroundActivities) {
14273+ changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14274+ }
14275+ if (changes != 0) {
14276+ if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14277+ app.memImportance = importance;
14278+ app.foregroundActivities = foregroundActivities;
14279+ int i = mPendingProcessChanges.size()-1;
14280+ ProcessChangeItem item = null;
14281+ while (i >= 0) {
14282+ item = mPendingProcessChanges.get(i);
14283+ if (item.pid == app.pid) {
14284+ if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14285+ break;
14286+ }
14287+ i--;
14288+ }
14289+ if (i < 0) {
14290+ // No existing item in pending changes; need a new one.
14291+ final int NA = mAvailProcessChanges.size();
14292+ if (NA > 0) {
14293+ item = mAvailProcessChanges.remove(NA-1);
14294+ if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14295+ } else {
14296+ item = new ProcessChangeItem();
14297+ if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14298+ }
14299+ item.changes = 0;
14300+ item.pid = app.pid;
14301+ item.uid = app.info.uid;
14302+ if (mPendingProcessChanges.size() == 0) {
14303+ if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14304+ "*** Enqueueing dispatch processes changed!");
14305+ mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14306+ }
14307+ mPendingProcessChanges.add(item);
14308+ }
14309+ item.changes |= changes;
14310+ item.importance = importance;
14311+ item.foregroundActivities = foregroundActivities;
14312+ if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14313+ + Integer.toHexString(System.identityHashCode(item))
14314+ + " " + app.toShortString() + ": changes=" + item.changes
14315+ + " importance=" + item.importance
14316+ + " foreground=" + item.foregroundActivities
14317+ + " type=" + app.adjType + " source=" + app.adjSource
14318+ + " target=" + app.adjTarget);
1419714319 }
1419814320
1419914321 return app.curRawAdj;
0 commit comments