Merge "Extend process observer to be usable for media routing." into jb-dev

This commit is contained in:
Dianne Hackborn
2012-05-31 19:04:44 -07:00
committed by Android (Google) Code Review
5 changed files with 158 additions and 23 deletions

View File

@ -1359,6 +1359,13 @@ public class ActivityManager {
*/
public int lastTrimLevel;
/**
* Constant for {@link #importance}: this is a persistent process.
* Only used when reporting to process observers.
* @hide
*/
public static final int IMPORTANCE_PERSISTENT = 50;
/**
* Constant for {@link #importance}: this process is running the
* foreground UI.

View File

@ -20,6 +20,7 @@ package android.app;
oneway interface IProcessObserver {
void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities);
void onImportanceChanged(int pid, int uid, int importance);
void onProcessDied(int pid, int uid);
}

View File

@ -176,6 +176,7 @@ public final class ActivityManagerService extends ActivityManagerNative
static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
static final boolean DEBUG_VISBILITY = localLOGV || false;
static final boolean DEBUG_PROCESSES = localLOGV || false;
static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
static final boolean DEBUG_PROVIDER = localLOGV || false;
static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
static final boolean DEBUG_USER_LEAVING = localLOGV || false;
@ -764,8 +765,24 @@ public final class ActivityManagerService extends ActivityManagerNative
boolean mAutoStopProfiler = false;
String mOpenGlTraceApp = null;
static class ProcessChangeItem {
static final int CHANGE_ACTIVITIES = 1<<0;
static final int CHANGE_IMPORTANCE= 1<<1;
int changes;
int uid;
int pid;
int importance;
boolean foregroundActivities;
}
final RemoteCallbackList<IProcessObserver> mProcessObservers
= new RemoteCallbackList<IProcessObserver>();
ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
final ArrayList<ProcessChangeItem> mPendingProcessChanges
= new ArrayList<ProcessChangeItem>();
final ArrayList<ProcessChangeItem> mAvailProcessChanges
= new ArrayList<ProcessChangeItem>();
/**
* Callback of last caller to {@link #requestPss}.
@ -855,7 +872,7 @@ public final class ActivityManagerService extends ActivityManagerNative
static final int CLEAR_DNS_CACHE = 28;
static final int UPDATE_HTTP_PROXY = 29;
static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
static final int DISPATCH_PROCESSES_CHANGED = 31;
static final int DISPATCH_PROCESS_DIED = 32;
static final int REPORT_MEM_USAGE = 33;
@ -1195,11 +1212,8 @@ public final class ActivityManagerService extends ActivityManagerNative
}
break;
}
case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
final int pid = msg.arg1;
final int uid = msg.arg2;
final boolean foregroundActivities = (Boolean) msg.obj;
dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
case DISPATCH_PROCESSES_CHANGED: {
dispatchProcessesChanged();
break;
}
case DISPATCH_PROCESS_DIED: {
@ -2260,19 +2274,43 @@ public final class ActivityManagerService extends ActivityManagerNative
void reportResumedActivityLocked(ActivityRecord r) {
//Slog.i(TAG, "**** REPORT RESUME: " + r);
final int identHash = System.identityHashCode(r);
updateUsageStats(r, true);
}
private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
private void dispatchProcessesChanged() {
int N;
synchronized (this) {
N = mPendingProcessChanges.size();
if (mActiveProcessChanges.length < N) {
mActiveProcessChanges = new ProcessChangeItem[N];
}
mPendingProcessChanges.toArray(mActiveProcessChanges);
mAvailProcessChanges.addAll(mPendingProcessChanges);
mPendingProcessChanges.clear();
if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
}
int i = mProcessObservers.beginBroadcast();
while (i > 0) {
i--;
final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
if (observer != null) {
try {
observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
for (int j=0; j<N; j++) {
ProcessChangeItem item = mActiveProcessChanges[j];
if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
+ item.pid + " uid=" + item.uid + ": "
+ item.foregroundActivities);
observer.onForegroundActivitiesChanged(item.pid, item.uid,
item.foregroundActivities);
}
if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
+ item.pid + " uid=" + item.uid + ": " + item.importance);
observer.onImportanceChanged(item.pid, item.uid,
item.importance);
}
}
} catch (RemoteException e) {
}
}
@ -10802,6 +10840,13 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
ProcessChangeItem item = mPendingProcessChanges.get(i);
if (item.pid == app.pid) {
mPendingProcessChanges.remove(i);
mAvailProcessChanges.add(item);
}
}
mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
// If the caller is restarting this app, then leave it in its
@ -13734,9 +13779,6 @@ public final class ActivityManagerService extends ActivityManagerNative
return (app.curAdj=app.maxAdj);
}
final boolean hadForegroundActivities = app.foregroundActivities;
app.foregroundActivities = false;
app.keeping = false;
app.systemNoUi = false;
@ -13744,18 +13786,22 @@ public final class ActivityManagerService extends ActivityManagerNative
// important to least, and assign an appropriate OOM adjustment.
int adj;
int schedGroup;
boolean foregroundActivities = false;
boolean interesting = false;
BroadcastQueue queue;
if (app == TOP_APP) {
// The last app on the list is the foreground app.
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = Process.THREAD_GROUP_DEFAULT;
app.adjType = "top-activity";
app.foregroundActivities = true;
foregroundActivities = true;
interesting = true;
} else if (app.instrumentationClass != null) {
// Don't want to kill running instrumentation.
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = Process.THREAD_GROUP_DEFAULT;
app.adjType = "instrumentation";
interesting = true;
} else if ((queue = isReceivingBroadcast(app)) != null) {
// An app that is currently receiving a broadcast also
// counts as being in the foreground for OOM killer purposes.
@ -13791,7 +13837,7 @@ public final class ActivityManagerService extends ActivityManagerNative
boolean hasStoppingActivities = false;
// Examine all activities if not already foreground.
if (!app.foregroundActivities && activitiesSize > 0) {
if (!foregroundActivities && activitiesSize > 0) {
for (int j = 0; j < activitiesSize; j++) {
final ActivityRecord r = app.activities.get(j);
if (r.visible) {
@ -13802,7 +13848,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
schedGroup = Process.THREAD_GROUP_DEFAULT;
app.hidden = false;
app.foregroundActivities = true;
foregroundActivities = true;
break;
} else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
@ -13810,13 +13856,13 @@ public final class ActivityManagerService extends ActivityManagerNative
app.adjType = "pausing";
}
app.hidden = false;
app.foregroundActivities = true;
foregroundActivities = true;
} else if (r.state == ActivityState.STOPPING) {
// We will apply the actual adjustment later, because
// we want to allow this process to immediately go through
// any memory trimming that is in effect.
app.hidden = false;
app.foregroundActivities = true;
foregroundActivities = true;
hasStoppingActivities = true;
}
}
@ -13839,6 +13885,10 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
if (app.foregroundServices) {
interesting = true;
}
if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
// We don't want to kill the current heavy-weight process.
adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
@ -14188,12 +14238,84 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
app.curAdj = adj;
app.curSchedGroup = schedGroup;
int importance = app.memImportance;
if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
app.curAdj = adj;
app.curSchedGroup = schedGroup;
if (!interesting) {
// For this reporting, if there is not something explicitly
// interesting in this process then we will push it to the
// background importance.
importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
} else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
} else if (adj >= ProcessList.SERVICE_B_ADJ) {
importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
} else if (adj >= ProcessList.HOME_APP_ADJ) {
importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
} else if (adj >= ProcessList.SERVICE_ADJ) {
importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
} else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
} else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
} else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
} else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
} else {
importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
}
}
if (hadForegroundActivities != app.foregroundActivities) {
mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
app.foregroundActivities).sendToTarget();
int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
if (foregroundActivities != app.foregroundActivities) {
changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
}
if (changes != 0) {
if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
app.memImportance = importance;
app.foregroundActivities = foregroundActivities;
int i = mPendingProcessChanges.size()-1;
ProcessChangeItem item = null;
while (i >= 0) {
item = mPendingProcessChanges.get(i);
if (item.pid == app.pid) {
if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
break;
}
i--;
}
if (i < 0) {
// No existing item in pending changes; need a new one.
final int NA = mAvailProcessChanges.size();
if (NA > 0) {
item = mAvailProcessChanges.remove(NA-1);
if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
} else {
item = new ProcessChangeItem();
if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
}
item.changes = 0;
item.pid = app.pid;
item.uid = app.info.uid;
if (mPendingProcessChanges.size() == 0) {
if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
"*** Enqueueing dispatch processes changed!");
mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
}
mPendingProcessChanges.add(item);
}
item.changes |= changes;
item.importance = importance;
item.foregroundActivities = foregroundActivities;
if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
+ Integer.toHexString(System.identityHashCode(item))
+ " " + app.toShortString() + ": changes=" + item.changes
+ " importance=" + item.importance
+ " foreground=" + item.foregroundActivities
+ " type=" + app.adjType + " source=" + app.adjSource
+ " target=" + app.adjTarget);
}
return app.curRawAdj;

View File

@ -69,6 +69,7 @@ class ProcessRecord {
int curSchedGroup; // Currently desired scheduling class
int setSchedGroup; // Last set to background scheduling class
int trimMemoryLevel; // Last selected memory trimming level
int memImportance; // Importance constant computed from curAdj
boolean serviceb; // Process currently is on the service B list
boolean keeping; // Actively running code so don't kill due to that?
boolean setIsForeground; // Running foreground UI when last set?

View File

@ -395,6 +395,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
pid, uid, foregroundActivities).sendToTarget();
}
@Override
public void onImportanceChanged(int pid, int uid, int importance) {
}
@Override
public void onProcessDied(int pid, int uid) {
mHandler.obtainMessage(MSG_PROCESS_DIED, pid, uid).sendToTarget();