donut snapshot
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index bd79d1d..89f854e 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -2884,7 +2884,7 @@
if (gp.gids == null) {
gp.gids = mGlobalGids;
}
-
+
final int N = pkg.requestedPermissions.size();
for (int i=0; i<N; i++) {
String name = pkg.requestedPermissions.get(i);
@@ -3755,7 +3755,7 @@
}
}
}
-
+
private void updateSettingsLI(String pkgName, File tmpPackageFile,
String destFilePath, File destPackageFile,
File destResourceFile,
@@ -4220,7 +4220,7 @@
synchronized (mPackages) {
if ( (deletedPs != null) && (deletedPs.sharedUser != null)) {
// remove permissions associated with package
- mSettings.updateSharedUserPerms (deletedPs);
+ mSettings.updateSharedUserPermsLP(deletedPs, mGlobalGids);
}
// Save settings now
mSettings.writeLP ();
@@ -6008,7 +6008,15 @@
}
}
- private void updateSharedUserPerms (PackageSetting deletedPs) {
+ /*
+ * Update the shared user setting when a package using
+ * specifying the shared user id is removed. The gids
+ * associated with each permission of the deleted package
+ * are removed from the shared user's gid list only if its
+ * not in use by other permissions of packages in the
+ * shared user setting.
+ */
+ private void updateSharedUserPermsLP(PackageSetting deletedPs, int[] globalGids) {
if ( (deletedPs == null) || (deletedPs.pkg == null)) {
Log.i(TAG, "Trying to update info for null package. Just ignoring");
return;
@@ -6037,13 +6045,14 @@
}
}
// Update gids
- int newGids[] = null;
- for (PackageSetting pkg:sus.packages) {
- newGids = appendInts(newGids, pkg.gids);
+ int newGids[] = globalGids;
+ for (String eachPerm : sus.grantedPermissions) {
+ BasePermission bp = mPermissions.get(eachPerm);
+ newGids = appendInts(newGids, bp.gids);
}
sus.gids = newGids;
}
-
+
private int removePackageLP(String name) {
PackageSetting p = mPackages.get(name);
if (p != null) {
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 5a02c4d..d4c27b7 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -533,6 +533,17 @@
mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
+ int max_events_per_sec = 35;
+ try {
+ max_events_per_sec = Integer.parseInt(SystemProperties
+ .get("windowsmgr.max_events_per_sec"));
+ if (max_events_per_sec < 1) {
+ max_events_per_sec = 35;
+ }
+ } catch (NumberFormatException e) {
+ }
+ mMinWaitTimeBetweenTouchEvents = 1000 / max_events_per_sec;
+
mQueue = new KeyQ();
mInputThread = new InputDispatcherThread();
@@ -3989,8 +4000,8 @@
}
} //end if target
- // TODO remove once we settle on a value or make it app specific
- if (action == MotionEvent.ACTION_DOWN) {
+ // Enable this for testing the "right" value
+ if (false && action == MotionEvent.ACTION_DOWN) {
int max_events_per_sec = 35;
try {
max_events_per_sec = Integer.parseInt(SystemProperties
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 51ee41a..ae790c9 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -9137,9 +9137,13 @@
+ " #" + i + ":");
r.dump(pw, prefix + " ");
} else if (inclOomAdj) {
- pw.println(String.format("%s%s #%2d: adj=%3d/%d %s",
+ pw.println(String.format("%s%s #%2d: adj=%4d/%d %s (%s)",
prefix, (r.persistent ? persistentLabel : normalLabel),
- i, r.setAdj, r.setSchedGroup, r.toString()));
+ i, r.setAdj, r.setSchedGroup, r.toString(), r.adjType));
+ if (r.adjSource != null || r.adjTarget != null) {
+ pw.println(prefix + " " + r.adjTarget
+ + " used by " + r.adjSource);
+ }
} else {
pw.println(String.format("%s%s #%2d: %s",
prefix, (r.persistent ? persistentLabel : normalLabel),
@@ -9303,6 +9307,16 @@
}
}
+ // Make sure we have no more records on the stopping list.
+ int i = mStoppingServices.size();
+ while (i > 0) {
+ i--;
+ ServiceRecord sr = mStoppingServices.get(i);
+ if (sr.app == app) {
+ mStoppingServices.remove(i);
+ }
+ }
+
app.executingServices.clear();
}
@@ -9432,6 +9446,24 @@
app.conProviders.clear();
}
+ // At this point there may be remaining entries in mLaunchingProviders
+ // where we were the only one waiting, so they are no longer of use.
+ // Look for these and clean up if found.
+ // XXX Commented out for now. Trying to figure out a way to reproduce
+ // the actual situation to identify what is actually going on.
+ if (false) {
+ for (int i=0; i<NL; i++) {
+ ContentProviderRecord cpr = (ContentProviderRecord)
+ mLaunchingProviders.get(i);
+ if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
+ synchronized (cpr) {
+ cpr.launchingApp = null;
+ cpr.notifyAll();
+ }
+ }
+ }
+ }
+
skipCurrentReceiverLocked(app);
// Unregister any receivers.
@@ -9880,6 +9912,10 @@
if (DEBUG_SERVICE) Log.v(TAG, "Bringing up service " + r.name
+ " " + r.intent);
+ // We are now bringing the service up, so no longer in the
+ // restarting state.
+ mRestartingServices.remove(r);
+
final String appName = r.processName;
ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
if (app != null && app.thread != null) {
@@ -12182,33 +12218,60 @@
return (app.curAdj=EMPTY_APP_ADJ);
}
- app.isForeground = false;
+ if (app.maxAdj <= FOREGROUND_APP_ADJ) {
+ // The max adjustment doesn't allow this app to be anything
+ // below foreground, so it is not worth doing work for it.
+ app.adjType = "fixed";
+ app.adjSeq = mAdjSeq;
+ app.curRawAdj = app.maxAdj;
+ app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
+ return (app.curAdj=app.maxAdj);
+ }
+
+ app.adjSource = null;
+ app.adjTarget = null;
// Determine the importance of the process, starting with most
// important to least, and assign an appropriate OOM adjustment.
int adj;
int N;
- if (app == TOP_APP || app.instrumentationClass != null
- || app.persistentActivities > 0) {
+ if (app == TOP_APP) {
// The last app on the list is the foreground app.
adj = FOREGROUND_APP_ADJ;
- app.isForeground = true;
+ app.adjType = "top";
+ } else if (app.instrumentationClass != null) {
+ // Don't want to kill running instrumentation.
+ adj = FOREGROUND_APP_ADJ;
+ app.adjType = "instr";
+ } else if (app.persistentActivities > 0) {
+ // Special persistent activities... shouldn't be used these days.
+ adj = FOREGROUND_APP_ADJ;
+ app.adjType = "pers";
} else if (app.curReceiver != null ||
(mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
// An app that is currently receiving a broadcast also
// counts as being in the foreground.
adj = FOREGROUND_APP_ADJ;
+ app.adjType = "broadcast";
} else if (app.executingServices.size() > 0) {
// An app that is currently executing a service callback also
// counts as being in the foreground.
adj = FOREGROUND_APP_ADJ;
- } else if (app.foregroundServices || app.forcingToForeground != null) {
+ app.adjType = "exec-service";
+ } else if (app.foregroundServices) {
// The user is aware of this app, so make it visible.
adj = VISIBLE_APP_ADJ;
+ app.adjType = "foreground-service";
+ } else if (app.forcingToForeground != null) {
+ // The user is aware of this app, so make it visible.
+ adj = VISIBLE_APP_ADJ;
+ app.adjType = "force-foreground";
+ app.adjSource = app.forcingToForeground;
} else if (app == mHomeProcess) {
// This process is hosting what we currently consider to be the
// home app, so we don't want to let it go into the background.
adj = HOME_APP_ADJ;
+ app.adjType = "home";
} else if ((N=app.activities.size()) != 0) {
// This app is in the background with paused activities.
adj = hiddenAdj;
@@ -12216,12 +12279,14 @@
if (((HistoryRecord)app.activities.get(j)).visible) {
// This app has a visible activity!
adj = VISIBLE_APP_ADJ;
+ app.adjType = "visible";
break;
}
}
} else {
// A very not-needed process.
adj = EMPTY_APP_ADJ;
+ app.adjType = "empty";
}
// By default, we use the computed adjustment. It may be changed if
@@ -12237,15 +12302,19 @@
if (adj > BACKUP_APP_ADJ) {
if (DEBUG_BACKUP) Log.v(TAG, "oom BACKUP_APP_ADJ for " + app);
adj = BACKUP_APP_ADJ;
+ app.adjType = "backup";
}
}
if (app.services.size() != 0 && adj > FOREGROUND_APP_ADJ) {
// If this process has active services running in it, we would
// like to avoid killing it unless it would prevent the current
- // application from running.
+ // application from running. By default we put the process in
+ // with the rest of the background processes; as we scan through
+ // its services we may bump it up from there.
if (adj > hiddenAdj) {
adj = hiddenAdj;
+ app.adjType = "services";
}
final long now = SystemClock.uptimeMillis();
// This process is more important if the top activity is
@@ -12260,12 +12329,7 @@
// of the background processes.
if (adj > SECONDARY_SERVER_ADJ) {
adj = SECONDARY_SERVER_ADJ;
- }
- } else {
- // This service has been inactive for too long, just
- // put it with the rest of the background processes.
- if (adj > hiddenAdj) {
- adj = hiddenAdj;
+ app.adjType = "started-services";
}
}
}
@@ -12295,6 +12359,9 @@
if (adj > clientAdj) {
adj = clientAdj > VISIBLE_APP_ADJ
? clientAdj : VISIBLE_APP_ADJ;
+ app.adjType = "service";
+ app.adjSource = cr.binding.client;
+ app.adjTarget = s.serviceInfo.name;
}
}
HistoryRecord a = cr.activity;
@@ -12305,6 +12372,9 @@
(a.state == ActivityState.RESUMED
|| a.state == ActivityState.PAUSING)) {
adj = FOREGROUND_APP_ADJ;
+ app.adjType = "service";
+ app.adjSource = a;
+ app.adjTarget = s.serviceInfo.name;
}
}
}
@@ -12318,6 +12388,7 @@
// CONTENT_PROVIDER_ADJ, which is just shy of EMPTY.
if (adj > CONTENT_PROVIDER_ADJ) {
adj = CONTENT_PROVIDER_ADJ;
+ app.adjType = "pub-providers";
}
Iterator jt = app.pubProviders.values().iterator();
while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
@@ -12342,7 +12413,10 @@
client, myHiddenAdj, TOP_APP);
if (adj > clientAdj) {
adj = clientAdj > FOREGROUND_APP_ADJ
- ? clientAdj : FOREGROUND_APP_ADJ;
+ ? clientAdj : FOREGROUND_APP_ADJ;
+ app.adjType = "provider";
+ app.adjSource = client;
+ app.adjTarget = cpr.info.name;
}
}
}
@@ -12352,6 +12426,8 @@
if (cpr.externals != 0) {
if (adj > FOREGROUND_APP_ADJ) {
adj = FOREGROUND_APP_ADJ;
+ app.adjType = "provider";
+ app.adjTarget = cpr.info.name;
}
}
}
@@ -12366,7 +12442,7 @@
}
app.curAdj = adj;
- app.curSchedGroup = (adj > VISIBLE_APP_ADJ && !app.persistent)
+ app.curSchedGroup = adj > VISIBLE_APP_ADJ
? Process.THREAD_GROUP_BG_NONINTERACTIVE
: Process.THREAD_GROUP_DEFAULT;
@@ -12467,28 +12543,6 @@
int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP);
- //Log.i(TAG, "Computed adj " + adj + " for app " + app.processName);
- //Thread priority adjustment is disabled out to see
- //how the kernel scheduler performs.
- if (false) {
- if (app.pid != 0 && app.isForeground != app.setIsForeground) {
- app.setIsForeground = app.isForeground;
- if (app.pid != MY_PID) {
- if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(TAG, "Setting priority of " + app
- + " to " + (app.isForeground
- ? Process.THREAD_PRIORITY_FOREGROUND
- : Process.THREAD_PRIORITY_DEFAULT));
- try {
- Process.setThreadPriority(app.pid, app.isForeground
- ? Process.THREAD_PRIORITY_FOREGROUND
- : Process.THREAD_PRIORITY_DEFAULT);
- } catch (RuntimeException e) {
- Log.w(TAG, "Exception trying to set priority of application thread "
- + app.pid, e);
- }
- }
- }
- }
if (app.pid != 0 && app.pid != MY_PID) {
if (app.curRawAdj != app.setRawAdj) {
if (app.curRawAdj > FOREGROUND_APP_ADJ
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index 3f59710..544d034 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -58,7 +58,6 @@
int setAdj; // Last set OOM adjustment for this process
int curSchedGroup; // Currently desired scheduling class
int setSchedGroup; // Last set to background scheduling class
- boolean isForeground; // Is this app running the foreground UI?
boolean setIsForeground; // Running foreground UI when last set?
boolean foregroundServices; // Running any services that are foreground?
boolean bad; // True if disabled in the bad process list
@@ -73,6 +72,9 @@
BroadcastRecord curReceiver;// receiver currently running in the app
long lastRequestedGc; // When we last asked the app to do a gc
int lastPss; // Last pss size reported by app.
+ String adjType; // Debugging: primary thing impacting oom_adj.
+ Object adjSource; // Debugging: option dependent object.
+ Object adjTarget; // Debugging: target component impacting oom_adj.
// contains HistoryRecord objects
final ArrayList activities = new ArrayList();
@@ -151,8 +153,7 @@
pw.print(" set="); pw.println(setAdj);
pw.print(prefix); pw.print("curSchedGroup="); pw.print(curSchedGroup);
pw.print(" setSchedGroup="); pw.println(setSchedGroup);
- pw.print(prefix); pw.print("isForeground="); pw.print(isForeground);
- pw.print(" setIsForeground="); pw.print(setIsForeground);
+ 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);